Как стать автором
Обновить

Комментарии 87

НЛО прилетело и опубликовало эту надпись здесь

Самое интересное в STL — контейнеры, а вот их я бы неопытному разработчику крайне не советовал применять на микроконтроллерах. Да, их можно "правильно приготовить", но многие ли новички знают, как именно?
Вообще, имхо, при программировании под микроконтроллеры весьма разумно перенять подходы, принятые в линуксовом ядре. Списки, таскание контекста в предвыделенных структурах и жонглирование членством их в списках, структуры данных с использованием container_of для доступа к содержимому, и все такое прочее.

Почему только контейнеры? Алгоритмы тоже ничего, от банальных std::any_of и std::accumulate до всяких std::inner_product.

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

Кроме контейнеров такой сущностью может быть, например, обычный сишный массив — std::begin и std::end возвращают всё как надо.

Ну так-то да. Но потом джуны начинают морщить лоб, рвать волосы и терять самооценку, попытавшись создать std::begin от массива, переданного в параметрах функции — "ну как же, ну ведь с глобальным массивом же работало!", и все это потому, что массив, переданный через параметры, имеет sizeof () равный sizeof-у указателя, а не всего массива, и итератор не создается :)
Не подумайте, что я против итераторов или алгоритмов. Просто лично у меня как-то с ними не складывается. Не особо нужны, поэтому в голове не задерживаются, приходится лазать в книжку, поэтому стараюсь не использовать, поэтому в голове не задерживаются, и так далее, самоподдерживающийся процесс. Да и на плюсах я уже очень давно не пишу… А когда писал, плюсы были совсем не такие, как сейчас.

Ну так-то да. Но потом джуны начинают морщить лоб, рвать волосы и терять самооценку, попытавшись создать std::begin от массива, переданного в параметрах функции — "ну как же, ну ведь с глобальным массивом же работало!", и все это потому, что массив, переданный через параметры, имеет sizeof () равный sizeof-у указателя, а не всего массива, и итератор не создается :)

Щас бы использовать встроенные массивы вместо std::array

Мне не совсем понятно, что значит, научился "программировать микроконтроллеры". С моей точки зрения все 7 пунктов это тот минимум, который нужно знать для того, чтобы научиться "программировать микроконтроллеры". А чтобы понять тонкости и научится оптимально использовать ресурсы микроконтроллера, думаю, времени надо поболе. Так то, чтиво брошюрки на ядро ARM v7 reference manual на 2700 страниц займет достаточно времени. Если перейти на другое ядро, например, RISC V, там таких брошюрок несколько, а еще прибавить к этому брошюрки по С++, там и жизнь пройдет, а не только 3 года.

Увы, имхо, misra c требует вещей, которые после некоторого порога сложности проекта (очень небольшого) приводят не к упрощению и большей контролируемости проекта, а наоборот.

Верно. Но люди, которые пишут прошивки для простых, но очень надёжных вещей от этого не перестают быть теми, кто «научился программировать микроконтроллеры». Хоть и не знают ни STL, ни графических библиотек.
Что делать, если ты уже научился программировать микроконтроллеры?

Создать на них, наконец, что-то стоящее.

Людей, которые могут генерировать стоящие идеи, гораздо меньше чем людей, которые умеют программировать. В итоге мы видим очередную погодную станцию или очередного бота для телеграмма.

И я о том же. Сначала кажется, что для создания чего-то стоящего не хватает квалификации, а потом оказывается, что не хватает фантазии.

Но тут есть и положительный момент — не обязательно дожидаться пока вы станете гуру программирования — шедевры можно создавать прямо сейчас!
Откройте для себя чудесный мир программируемой логики FPGA. Зачем вам этот последовательный мир микроконтроллеров, в нашем параллельном мире process'ов, always'ов и комбинационной логики тоже интересно.

Кстати, на ПЛИС можно собрать свой собственный процессор, со своим набором команд, придумать к нему ассемблеры, компиляторы и тд. Ну или воспользоваться чем-то уже готовым, но сделанным на логике, например, RISC-V, MIPS, Cortex M3/M0, NIOS, MicroBlaze, PicoBlaze.
Действительно, и чего это мы тормозим, когда есть такой волшебный мир FPGA? У этого мира есть только один недостаток — порог входа размером с Эверест, а так, да, FPGA — это круто.

Да нет там никакого особенного порога входа. Отладочная плата для "пионерских поделок" стоит $40, софт бесплатный, хороший учебник — бесплатный, чип со вполне приличной для многих задач емкостью — от $6 до $12.
Была бы нормальная задача, а реализовать — несложно.

а реализовать — несложно.

Если всё так просто, то где (буквально миллионы, как в случае с Ардуино) пионеров с платами FPGA в руках?

Так задач для FPGA немного, тем более интересных пионерам.

эээ где где бесплатный софт? Какую ПЛИС не возьми, софт бесплатен только до определённого размера проекта, а дальше всё… плати. Поиграться бесплатно, а что-то сделать — покупай… подписку! Даже для бытовых(современных) нужд ограничений уже слишком много. Итам, в паралельном мире ещё больше вещей взрывающих мозг, таких как БЫСТРОДЕЙСТВИЕ схемы зависящее от её сложности, необходимость продумывать синхронизацию между макроблоками из-за переменной задержки сигнала, зависящей от сложности логической функции блока…
Приличнаая емкость, это 32 макроячейки? На которой элементарный счетчик едва соберёшь…
Приличнаая емкость, это 32 макроячейки?


Сейчас играю: ZYNQ 7010, 2 core 666MHz ,22 KLUT — 256 MB DDR3 128 Mb flash — вполне серьезная игрушка за $13.5 c бесплатной доставкой aliexpress.com/item/1005001500766274.html
Впрочем согласен, что у FPGA не совсем та же область применения как у контроллеров.И порог вхождения немного другой, не скажу, что выше, просто другой. Товарищ вверху habr.com/ru/post/532744/#comment_22416460 немного сам себе противоречит с реализацией микроконтроллеров на FPGA. Их поэтому и делают, что микроконтроллеры иногда удобней чем RTL.
Не противоречит. Типичный представитель таких МК — современные чипсеты на материнских платах компьютеров. Удобно… прошивкой меняешь схемотехнику чипсета, исправляя «аппаратные» косяки и обновляя аппаратное ядро встроенного контроллера, управляющего работой всего чипсета, проводящего самодиагностику и прочее… по сути большой FPGA на сотни тысяч LUT… не хватает таймера контроллеру? добавим… ещё каналов DMA нужно? добавим… в случае с железным МК пришлось бы перепаивать микросхему для апгрейда.
Прочитайте его коммент еще раз:
Зачем вам этот последовательный мир микроконтроллеров, в нашем параллельном мире

"вполне серьезная игрушка за $13.5 c бесплатной доставкой aliexpress.com/item/1005001500766274"
Забавно, они продают плату от кондиционера как девборду. Цинк за копейки. Хорошая основа для разработок.

Это контрольный блок от майнера в целом(ebaz4205) а не только его вентиляторов. Видимо много их разбирают и утилизируют, поэтому за бесценок.
А вот асики видимо выбрасывают.

Тот чип, что имею ввиду — это младший альтеровский Cyclone-IV, стоит меньше $10 в розницу, паябельный вручную корпус, 6 с лишним тысяч триггеров, 30 штук блоков памяти по 9 килобит. Я на нем расширение ввода-вывода для своего нынешнего устройства делал: пачка UART-ов (больше дюжины) через быстрый SPI с удобным для основного процессора протоколом, развязка клоковых доменов, пачка GPIO-шек (у основного процессора со свободными пинами напряженка), софтверно-переключаемые внешние интерфейсы, конфигурируемые пины плат расширения. Все это удовольствие на верилоге написалось с нуля за пару недель без предыдущего опыта работы на verilog, и спасло меня от громадной возни с кучей противоестественных ограничений, которых было бы уйма, если бы я попытался все сделать на основном процессоре.
Кстати, бесплатность софта сохраняется вплоть до очень немаленьких чипов. Вроде бы 4-е циклоны все поддерживаются на бесплатном квартусе. Ну а когда один чип стоит за тысячу баксов — тут уж и софт можно купить.

Добавлю еще применение — контроллер дисплея в помощь мелкому микроконтроллеру. От просто кадровой обновлялки с буферной памятью до видеоускорителя с возможностью рисования примитивов, наложений и т.п.
Софт действительно бесплатный, причем для огромного числа емких кристаллов. У Xilinx, например, полностью бесплатна линейка Spartan-7 и Artix-7, а это, на секундочку, кристаллы 100к и 200к логики соответственно, частично Kintex-7, Kintex US, Ускорители Alveo, Zynq-7000 не говоря уже о семействе ZU+ (с огромных количеством плюх). Рекомендую ознакомиться с UG973 таблица 1.
Можно, и это круто, но зачем ??? Потратить год и написать никому не нужную фигню ??? Это здорово для обучения (впрочем не факт) и совершенно бесполезно.
И эту фигню можно написать и на PC, раз в десять быстрее(хотя бы за счет более короткого цикла изменение/компиляция/запуск).
Первый процессор Novix появился в июне 1985 года и получил обозначение NC4016. Он работал с тактовой частотой до 7,5 МГц и показывал скорость до 10 миллионов операций в секунду — впечатляющий результат для того времени. Все операции NC4016 исполнялись за один такт.

Чужие: странная архитектура инопланетных компьютеров

P.S. Ардуино шилд c GPU, FPGA, HDMI, и Python поддержкой для игр и аудиовидео Gameduino 3X Dazzler by Excamera Labs. J1 процессор запущен в FPGA.

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

1. FPGA намного дороже и менее энергоэффективны по сравнению с микроконтроллерами.

2. FPGA подходит для выполнения очень быстрого IO на множестве каналов, но таких задач практически не бывает в «обычных» устройствах.
То есть собрать цифровой 64 канальный осциллограф с частотой сэмплирования в сотни мегагерц — тут FPGA подойдет. Написать GUI для этого осциллографа — нужен микроконтроллер.

3.
на ПЛИС можно собрать свой собственный процессор, со своим набором команд, придумать к нему ассемблеры, компиляторы

ЗАЧЕМ?!!! Зачем делать тот пласт работ, что проделал Atmel или ST, если можно просто взять их готовый микроконтроллер, который будет дешевле в 100 раз, в 10 раз экономичнее и в несколько раз быстрее.

Мое мнение — FPGA нужна для очень узкого класса задач, где нужно очень быстро обрабатывать по несложным алгоритмам параллельные данные — головки самонаведения ракет, PCI-Express переходник, осциллографы, сетевое оборудование и т.п.
Сфера применения микроконтроллеров гораздо шире.
С++ и STL отличная вещь, но для контроллеров без нормального MMU очень опасна, из-за фрагментации памяти. Не пользуйтесь ими на МК, если не понимаете в деталях что происходит и не принимаете специальных мер для работы с памятью.
Автору. Не давайте таких советов, сначала разберитесь сами, микроконтроллеры бывают разные.
Это относится только к освобождению динамической памяти, и контейнерам STL, которые его используют. В остальном использование C++ безопасно, может быть не менее эффективно чем использование C, и даёт массу преимуществ, в частности лучшую читаемость кода, и возможность обнаружения большего процента ошибок на этапе компиляции.
Пишу на плюсах для систем с нормальным MMU и на С для систем без него(или с ним но ниже, как в ядре OS). И стараюсь их не смешивать. Наверноге дураки пишут на чистом С ядро линукса?
Очень легко сбиться и использовать STL с аллокациями, особенно когда пишешь сразу на обе стороны (и PC и контроллер ) Я люблю с++, но в контроллерах ему не место (ИМХО), и Вы меня не переубедите, я раньше выйду на пенсию :)
Наверноге дураки пишут на чистом С ядро линукса?

Технически это не "чистый C", а его GNU-тый диалект. Но да, дураки.


Я люблю с++, но в контроллерах ему не место (ИМХО), и Вы меня не переубедите, я раньше выйду на пенсию :)

А, то есть на микроконтроллерах не нужны ни нормальные массивы, ни пространства имён, ни сокрытие данных, ни constexpr, ни более строгая типизация, ни шаблоны, ни целая пачка алгоритмов из std. Деды терпели — и ты потерпи.

На контроллерах с тем же самым gcc какой то другой GNU?
" Да дураки "- нет слов… Все отнять и поделить?
Псс. Да я не против, можете мигать светодиодом и дальше хоть на расте.

Так ровно наоборот, в том-то и дело, что для элементарщины типа мигания светодиодом простой Си подходит отлично. Проблемы и недостатки Си начинают проявляться когда у вас проект у которого на несколько порядков бо́льшая сложность и на несколько порядков бо́льший объем кодовой базы, и это не зависит от того, насколько вы квалифицированный сишник (как раз справедливо обратное, чем выше у вас квалификация, тем раньше вы это поймёте).
Поэтому до осознания этого просто надо дорасти.

Это и правда и неправда. Структура и надежность программы в большей степени зависит от продуманности ее архитектуры и квалификации программиста и в гораздо меньшей степени от языка. С++ удобнее чем С, но это далеко не самый важный фактор. В больших проектах архитектор программы важнее программиста( даже если это один и тот же человек). И в одном проекте может быть много языков. И выбор языка не всегда связан с удобством программиста. До осознания отсутствия королевских путей и серебрянных пуль еще надо дорасти, чего Вам и желаю.

И выбор языка не всегда связан с удобством программиста.
А я и не ставил во главу угла «удобство для программиста», в соседнем комментарии я наоборот говорил совершенно другое:
Поэтому любой серьезный коммерческий проект — это именно находждение баланса между производительностью, скоростью разработки, ценой и безопасностью.
Ошибки совершают все, а те, кто говорят что не совершают — те врут. Чем больше проект — тем больше вероятность в нем ошибок (спросите у парней из PVS-Studio, они вам много про это расскажут). Чем ответственнее применение изделия — тем больше цена ошибки. А на безопасность и надёжность язык влияет самым прямым образом, ибо тут все напрямую зависит от того, сколько в языке неочевидных и неоднозначных подводных камней, насколько он прощает и даже располагает к грязным хакам, насколько сильно он перекладывает ответственность за все на разработчика, и в целом от его концепций (типобезопасность, инструменты контроля владения). Cи в этом смысле до Cи++ как до Луны, а Cи++ в этом смысле как до Луны до Rust и Ada.
… от продуманности ее архитектуры
И тут, опять же, нужно помнить, что язык может как располагать к определенным требуемым архитектурным решениям, так и серьезно затруднять их реализацию. О том и речь, что когда у вас простая поделка — то ее можно писать на всем чем угодно, а когда вы пишите что-то серьезное, которое к тому же активно расширяется — то неправильно выбранный инструмент (который, как показали комментарии, многие выбирают не по рациональным доводам, а по «деды писали, я писал, так и будем жить, ну, нафиг ваши новоделы, я в них не хочу разбираться») может доставить много головной боли в будущем.
Вы комменты через один читаете? Причем тут деды и новоделы? Плюсы сильны вместе с динамической аллокацией. Раст вообще постороен на оптимизации(трассировке) времени жизни объектов компилятором. А контроллеры без MMU страдают фрагментацией памяти, поэтому требуют особой заботы при работе с ней. И рекомендовать использовать с++ и STL неопытным программистам на контроллерах — это подсунуть им хорошие грабли. А опытные -обойдутся и без советов программистов с 3 -5 летним стажем.
Плюсы сильны вместе с динамической аллокацией.
В плюсах есть много вещей, который серьезно помогают даже в системах вообще без malloc(), комментатор выше перечислил многие из них
Раст вообще постороен на оптимизации(трассировке) времени жизни объектов компилятором
Во-первых, так же как и с плюсами, Rust имеет много другой вкусноты (одна его система типов чего стоит), во-вторых, тоже может использоваться с минимумом динамических аллокаций (и в том числе помогает безопасно снизить их количество до минимума при необходимости).
рекомендовать использовать с++ и STL неопытным программистам на контроллерах — это подсунуть им хорошие грабли
Именно потому я и другие комментаторы под этой статьей написали, с чем именно нужно быть внимательными и рекомендовали ревью с более опытными товарищами.
опытные -обойдутся и без советов программистов с 3 -5 летним стажем.
А вот это однозначно не так. Тут работает известный парадокс, что именно «опытные» сильнее всего страдают закостенелостью мышления и облениваются. Человек много лет подряд успешно что-то пилил, владеет инструментами, имеет огромный опыт, и казалось бы все хорошо, но когда возникает естественная и обоснованная необходимость выйти за рамки привычного, то он либо активно противится освоению чего-то нового (уперто выдумывая любые даже самые бредовые аргументы), либо в принципе не рассматривает ничего кроме привычных ему инструментов, просто потому что не догадывается о преимуществах других (и вот для вторых такие советы могут быть очень полезными). Причем, чем больше стажа и опыта, тем сильнее это проявляется, и это не здоровый консерватизм (здоровый консерватизм — это очень правильно), это именно закостенелость доходящая до маразма, и в итоге вредящая и самому инженеру, и продукту, над которым он работает. И чаще всего такое встречается либо у олдовых эмбеддеров, либо у олдовых дельфистов (нетрудно догадаться, почему).
Я согласен, но
1 Дельфистам пофиг и мои и Ваши советы.
2 Закоренелым (закостенелые )железячникам тоже
3 остальным программистам тоже, если они вам непосредственно не подчиняются, впрочем если подчиняются то тоже пофиг.
Остались неопытные. А вот им -вредно.
С++ лучше учить не на микроконтроллерах
а Cи++ в этом смысле как до Луны до Rust и Ada.

Которым, в свою очередь, в этом смысле до Луны как до Coq и Agda.

Не слышал о таких. Интересно. Посмотрю.

Но на Coq и Agda софт таки не пишут :]

Почему же? Из кока вон экстрагируют, а на агде даже можно что-то успешно запускать.

. Наверноге дураки пишут на чистом С ядро линукса?
Тут во-первых надо иметь в виду, что когда начинали писать Linux (как и ntoskrnl, кстати), C++ ещё только начинал захватывать мир, был сыроват и не имел кучи вещей, которые имеет сегодня. Ну, а во-вторых, во главе разработки стоит благородный диктатор Линус, отношение которого к C++ он сам описывал как «А просто не нравится и всё», и с ним уже давно все расхотели спорить.
Могу привести контр-примеры, например EPOC32 и Symbian, которые прекрасно работали на устройствах с дохлыми процессорами и крохотной памятью, а ещё BeOS (и ее наследница Haiku). Все они были отличными ОС в техническом плане и умерли исключительно из-за факапов менеджмента. Ещё можно назвать ряд микроядер L4 (вариацию NICTA которого Qualcomm использует в своих чипах для телефонов), ну и частично ядро Zircon, которое Google пилит для своей новой Fuchsia.
C и libc отличная вещь, но для контроллеров без нормального MMU очень опасна, из-за фрагментации памяти.

Все будет опасным если если не разбираться и не понимать что проиходит, и не только в контексте программирования МК.

А по теме — С++ однозначно удобней и безопасней С в любых контекстах.
Во первых STL это не только контейнеры но и алгоритмы.
Во вторых уже давно есть std::array — контейнер без аллокации. И недавно добавили std::span, который на понядок удобней всяких (void*, size_t size).
Ну и как вишенка — все контейнеры, которые аллоцируют память, делают это через аллокатор. И вы вполне можете написать себе такой какой надо.
На мой взгляд — в области микроконтроллеров как раз не хватает людей с пониманием различных протоколов (I2C, SPI, MIPI/CSI) и их «правильных» имплементаций (с прерываниями или DMA вместо опроса). Вторая «болевая точка» — это управление потребляемой мощностью. А имплементация алгоритмов и структур данных действительно не так сильно отличается от десктопно/серверной.
Далеко не у всех микроконтроллеров ядро это ARM. И самое главное в программировании микроконтроллеров, это не 7 пунктов автора. Самое главное это разобраться как работает микроконтроллер, конкретный микроконтроллер. Иначе будет мучительно больно за потраченное время на реализацию той или иной «плюшки» уже имеющейся в базе или обнаружить что стандартная библиотека эмулирует работу UART вместо того, чтобы использовать аппаратный (UART просто пример).
m.habr.com/ru/post/27055 вот этот человек умеет «программировать» микроконтроллеры. Стиль статьи не технический, но очень хорошо передаёт то, что надо изучить в первую очередь, а не С++…
В 2020 году, компиляторы для МК вышли на такой уровень компиляции исходного кода, что выхлоп с Си и С++ не будет отличаться.

Боюсь вас удивить, но в выборе C vs C++ наиболее важным критерием является не «выхлоп» компилятора, а то, сколько у вас памяти, и как она распределяется.
Если у вас есть безразмерный heap — можете хоть на питоне писать (модное, кстати, направление для микроконтроллеров).
А вот если памяти лишней нет, да еще и распределять ее некому (кроме себя самого), то на плюсах писать конечно можно… но это уже искусство ради искусства.

Приведу достаточно продвинутый пример использования современного C++. Допустим есть класс для работы с LTDC и в функцию инициализации одной строкой передаются требуемые пины, пусть это будут 14 пинов для RGB444. Эта функция пробрасывает пины в более общую initRgb666(), а в качестве недостающих передаются PinDummy<>. Далее все пины передаются в функцию которая добавляет им правильные AF одновременно проверяя допустимость использования конкретных ног и если что выдается сообщение об ошибке с именами ошибочных пинов. И пины одним списком возвращаются обратно, уже с AF, затем этот список вместе с режимом, а можно использовать и список разных режимов, передается функции инициализации пинов из класса портов. Там к пинам подмешиваются режимы, удаляются PinDummy<> и вызывается конструктор очередного класса который сначала распаковывает все пины в обычный массив структур, затем сортирует его по трем параметрам при помощи std::ranges::sort() и далее идет код примерно на страницу который в цикле берет отсортированные данные и этого массива и после некоторых преобразований сохраняет их в другом массиве. Наконец есть еще небольшой класс который забирает массив у предыдущего и копирует, в такой-же массив, но меньшего размера. В самом конце вызывается функция, которая получает на вход массив с информацией о пинах/AF/режимах и выполняет их инициализацию. Итак, что же получится на выходе, если на входе было:


ltdc.initRgb444<PC6, PA4, PE15, PB1, PC0, PA11, PD3, PC7, PB11, PB10, PB9, PB8, PA3, PA10>();

Думаю даже многие из тех кто давно пишет на C++ удивились бы узнав, что получим мы следующее, даже при отключенной оптимизации:


ldr r0, [pc, #668]
bl 0x24000454

В R0 грузится адрес массива и этот массив расположен во флеше(!), а размер его 29 байт. Насколько это мало должно быть понятно из того, что 14 переданных пинов были с 5-ти портов с тремя разными AF. Фактически, поскольку в С++20 можно на этапе компиляции динамически выделять память, использовать виртуальные функции или std::vector, это все тоже могло там быть с нулевым оверхедом в рантайме. Использую С или ассм и близко ничего похожего не получишь, пора уже смириться с тем, что при правильном подходе С++ — это самый эффективный язык для эмбедда :)

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

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

В дизассемблер лезть не придется, получим или массив во флеше или программа не скомпилируется(для чего она должна быть написана с ошибками), а все потому, что от C++ можно явно это потребовать. Не случайно же настолько впечатляющий результат получается даже при отключенной оптимизации, когда один sort() занял бы в рантайме 3КБ флеша.
Добавили для простого массива const и он пойдет по флеш, добавили для класса constexpr/consteval и компилятор будет обязан его разместить там же, но константным класс стал только после создания, за которое отвечает конструктор, а в нем можно делать практически что угодно и совершенно бесплатно. Многие пишущие на C++ удивятся просто потому, что не знают о таких возможностях языка, на ПК они, например, не особо востребованы. Что уж говорить про тех, кто на С++ не пишет...

«Ядро Cortex-M3 компании ARM. Полное руководство Джозеф Ю».
Спасибо! есть на одном известн-… серв.... читаю!
Вчера встретил упоминание про специальные регистры отладки и таймер, а в pdf stm32 только скупая сноска, что мол читайте об этом у ARM

Автор во многом прав, но к некоторым пунктам я считаю нужным вставить свои 5 копеек.


Классы, ООП, виртуальные функции, умные указатели и т.п. — все это сильные помощники программисту
Совершенно верно. Правда, тут у монеты есть две стороны: с одной стороны, советую изучать и использовать именно идиоматичный C++, а не «Си с классами», с другой стороны, учитывая специфику разработки под МК, нужно хорошо понимать, как устроены инструменты, которые вы используете. Например, исключения на многих платформах могут давать оверхед по производительности либо раздувать размер прошивки, поэтому их часто отключают в настройках компилятора. std::string вместо char*-строк помогает избежать огромного количества ошибок, но при этом в современных стандартах для них запрещен CoV, из-за чего, опять же, растет потребление памяти и есть просадка в производительности. Поэтому обе стороны монеты тут сливаются в одну: изучайте современный идиоматичный C++, чтобы правильно использовать его внутренности. А именно, всякие там span, move-семантика и perfect forwarding, и т.д.
Отсюда же следует следущий пункт,
3. Открой для себя дивный мир STL
STL — отличная штука, экономящая много времени и спасающая от кучи головной боли. Но STL — это все-таки универсальное решение на все случаи жизни, а МК имеют свои специфику, например, память часто часто довольно серьезно ограничена, и поэтому нужно знать, как именно она выделяется и управляется в используемых контейнерах. В каких-то случаях очень уместными могут оказаться кастомные аллокаторы, в каких-то случаях даже уместно разрабатывать свои контейнеры (но с оглядкой на STL).
Изучай паттерны проектирования
Однозначно да. Позволяет избежать переизобретения велосипедов, помогает при поиске архитектурных решений. Только нужно иметь в виду, что паттерны — это не истина в последней инстанции. Бывает, что разработчик изучивший GoF начинат пихать прочитанное везде где можно и наворачивать конструкции над конструкциями. Наоборот. Это лишь примеры, эскизы, и применять их стоит гибко.
Тут мне особо написать нечего. О том что это такое, и для чего — написано бесчисленное количество трудов. Эффект от Юнит тестов и разработки через тестирования значительный. Данные тесты позволяют отловить много багов еще до того, как фиксы отдается в ОТ.
Однознано да. Но тут, как по мне, важно еще кое-что. Написание тестов — это как медицинское лечение зависимостей: ничего не получится, пока человек не поймет, что ему это надо и не захочет этого. Очень многие программисты своё нежелание изучать что-то новое и тратить время на написание тестов, чем только это не оправдывают: мол, «у нас своя специфика, такое нормально не протестировать». Обычно за этими аргументами скрывается или непонимание, что вообще можно и нужно тестировать (если у вас все задачи — это перекладывание байтиков между регистрами, то да, печаль), а во-вторых, что написание тестов требует правильной и хорошо спроектированной архитектуры: дробление функций и классов, четкое разделение компонентов на слои (HAL отдельно, протоколы отдельно, логика отдельно), минимизация прибитых гвоздями связей, переносимость (чтобы можно было гонять тесты на другом таргете), и т.д.

А что можно добавить к описанным пунктам… Выберите хороший стандарт кодирования. Во-первых, чтобы код был читаемый и опрятный, а во-вторых, чтобы минимизировать количество потенциальных ошибок. Тут уже упоминали MISRA C и MISRA C++, это самое то, чтобы начать.
Давайте свой код на review опытным товарищам. Это самый лучший способ от замыливания глаз и для получения реальных полезных знаний.
И изучите системы контроля версий. Лучше git, но хотя бы svn. До сих пор можно встретить конторы, где новая версия выпускается копированием кода в новую папочку, и это в XXI-то веке. Не надо так.
Под каждую систему (задачу) — свой подход.
Ну, например, невозможно впихнуть ARM везде, где только можно.

1. Во-первых, когда есть требования по потреблению — например, 80uA в спящем режиме, почти постоянным сном, просыпаешься только по внешним прерываниям или прерыванию от таймера, в остальное время ядро спит.

2. Планируется крупный тираж, и надо, чтобы было дёшево. Экономишь на железе на каждой копейке. Сравнивается твоё время на работу, «впихнуть в невпихуемое», и выбор компонентов на тираже.

3. В этом случае C++ — чисто для удобства, C — норма, ASM — круто, но долго. Пишешь код на C так, что в голове понимаешь, как оно будет компилиться. Ограничения по RAM и ROM.

Но это крайний случай, конечно. Но для дешёвых и энергоэффективных устройств распространён, в случае крупной партии.

(Начинал с PIC 16C622 N-дцать лет назад. Было очень критично. Архитектуру контроллера, ASM надо было знать на 200%, про схемотехнику не говорю. Запихнуть всё сложное в 2kW RAM, 128 bytes SRAM, 2kB EEPROM, эх… По 100_000 строк не было, каюсь)
Ну, например, невозможно впихнуть ARM везде, где только можно.

1. Во-первых, когда есть требования по потреблению — например, 80uA

Возможно. Есть режимы с часами ~ 3uA.
проект, в котором более 100000 строк (что не является большим количеством), становится практически не поддерживаемым на Си

Проект в более чем 100000 строк говорит о неумении писать код для контроллеров)

Прошу прощения, а какой вы предлагаете выход из ситуации, когда функционала и логики требуется действительно много? Поделитесь же своим "умением писать код для контроллеров", мы с интересом послушаем.

Такой выход и предлагаю — писать более оптимальный код. У меня ни разу не было нехватки ресурсов в AVR-ках, хотя писал на них достаточно многофункциональные распределенные АСУ.
Ну или берите Raspberry, а не контроллер, там вас ничто не ограничивает)

То, что у вас лично не было таких проектов и вам звало avr ничего не говорит о потребностях рынка. Вот у нас в задачах часто не хватает и 512 КБ флеша, хотя библиотек лишних нет, только голый cmsis и код достаточно оптимален. И да, 100к строк в большом проекте это не очень то и много.


Малина не ограничивает? Ну ну)) Огромное потребление и невозможность применения там, где нужен real-time.

Вы сейчас вообще о чем? Изначально речь шла о количестве строк и сущностей в исходном коде (что обычно линейно зависит от его функциональности, если не брать клинические случаи типа индусского кода с построчной оплатой), вы в ответ предлагает писать более оптимальный код и начинаете тему о ресурсах МК… И как как по-вашему связана оптимальность кода с объемом исходников и количестве сущностей в них? Если исходного кода много, то он не может быть предельно оптимизированным, так что ли?


Ну и да, как уже правильно сказали выше, если для вас 100к это прям невероятный объем, то вы просто ещё не сталкивались с целым пластом задач. И понимание проблематики поддержки большой кодовой базы придет тоже с опытом. Иными словами, в статье речь не про "кода много, бинарь большой, мы не влезем во флеш", а "кода много и он весь нужен, требуется заранее принимать меры для его безболезненной поддержки, чтобы уменьшить стоимость изменений и расширений и избежать нарастания технического долга".

Например, у нас на работе было время, когда пришло новое начальство, которое раньше для контроллеров код не писало. И начало писать его в своем привычном ООП-стиле «как для компьютеров». Число строк выросло на порядок, бинарник разросся, скорость работы тоже упала.
Я о том, что опытный алгоритмист в большинстве случаев сведет эти 100к строк к 10к.
Я о том, что опытный алгоритмист в большинстве случаев сведет эти 100к строк к 10к.
То есть не зная ровным счетом ничего о самом проекте и о том, кто его писал, вы беретесь рассуждать о том что код плохой и его писали плохие разработчики. Забавно.

Интересная у вас работа, что начальство само код пишет. Обычно начальство формулирует задачи и выстраивает процессы.

ООП по определению не может приводить к возрастанию числа строк на порядок. Просто потому, что суть ООП как раз в абстракциях от однообразных низкоуровневых конструкций и сокращении boilerplate кода. Более того, основополагающий принцип C++ «you don't use, you don't pay for», и именно благодаря ему C++ так популярен в проектах, критичных к производительности и потреблению ресурсов.

А бинарники часто раздуваются из-за бездумного использования универсальных библиотек. Недавно был хороший пример, когда функция типа isspace(), простейшая реализация которой умещается в одну строчку, в glibc представляло из себя монструозное нечто, и на это были вполне себе существенные причины. Это именно плата за универсальность, а когда у вас специфичная платформа и универсальность вам не нужна, язык не запрещает использовать альтернативы. Поэтому, например, в embedded вместо STL можно встретить использование ETL и uSTL, uClibc вместо libc, и т.д.

Что забавно, так это то, что несколько десятков лет назад (еще во времена ранних PIC'ов и 8051) матерые микроконтролерщики точно так же ругались и не принимали Си. Мол, умелый ассемблерщик напишет код гораздо компактнее и оптимальнее. Ну и где они теперь? В то время как если уметь готовить, C++ может дать очень хороший баланс между удобством и максимальной производительностью, выше уже приводили очень неплохие примеры.

На самом деле, обратных примеров я повидал немало: когда бывалые сишники, начиная работать в «десктопных» проектах, писали код, который был хоть и оптимизированный, но в остальном на который без слез взглянуть нельзя было, и спустя несколько лет пришлось все переписывать почти подчистую просто из-за невозможности нормально дальше с этим работать.
А разгадка одна: если у вас не наколенная поделка и не очередной бегущий огонек на светодиодах, а серьезный коммерческий проект с перспективами, то все становится гораздо сложнее.
На одной чаше весов действительно лежит «оптимальность кода», благо можно сэкономить на железе и поставить чип подешевле. А на другой чаше весов лежит безопасность (особенно если у вас железка работает в сети), и что гораздо важнее — скорость и стоимость разработки. Убытки от дыр и от пропущенных ошибок в серийных изделиях, упущенная выгода от более позднего выхода на рынок, чем у конкурентов, стоимость человеко-часов команды инженеров и накладных расходов на устранение регрессий — всё это может оказаться гораздо дороже, чем экономия на компонентах на плате.

Можно написать сверхоптимизированное ядро ОС на чистом ассемблере (MenuetOS и Kolibri не дадут соврать), но это будет очень долго и дорого. Можно даже веб-браузер с полной реализацией HTML5 и WebAPI и JS JIT написать сверхоптимально на чистом Си при большом желании, но такое безумство никому в голову не придет. Слишком долго и слишком дорого, даже если у вас есть целая армия «опытных алгоритмистов». Да и сами «опытные алгоритмисты» наврядли в это ввяжутся, ибо геморроя много, а отдача очень не скоро.
С безопасностью все еще веселее — вспомните Treck, который оптимизировали очень тщательно, который очень компактный и способный работать даже на дохлом bare metal, но с которым случился Ripple20, и последствия до сих пор расхлебать не могут.
Поэтому любой серьезный коммерческий проект — это именно находждение баланса между производительностью, скоростью разработки, ценой и безопасностью. И одной только командой «опытных алгоритмистов» этот баланс не найти. Этим «алгоритмистам» в любом случае потребуются еще подходящие инструменты.
Я рассуждал о принципах, а не о конкретных проектах.

Начальник отдела программистов. И сам писал код, и другим указывал, как.

Двольно смешно читать про превращение 100к строк в 10, да ещё и от "начальника". Есть огромный пласт проектов, где даже в условиях отличной архитектуры и хорошего кода без лишних библиотек объем все равно больше 100к.


И да, как показывает мой опыт офисной работы должность начальника никак не коррелируется ни с опытом разработки, ни с навыками. Пока что, то что вы пишите говорит лишь об обратном

должность начальника никак не коррелируется ни с опытом разработки, ни с навыками.


Я об этом и говорил. Речь о моем начальнике, а не обо мне.
«какие ещё пути развития могут быть у Embedded программистов»
Вот сидит Embed программист на горе со своим знанием IDE, микроконтроллера, С++,
а что запрограммировать ( «сделать что-то стоящее»(с) ) не знает :) Этому вопросу тоже стоит уделять внимание — куда приложить ваши знания и умения. Не моргать же всю жизнь светодиодами :)
С проблемами которые вы описываете OEM производители embedded софта столкнулись 20 лет назад — да все верно проект на N строк на M языке не поддерживаемый. Так же они прекрасно знали, что объем кода (собственно число строк близкий показатель) удваивается за полгода-год. И они не перешли на язык M++ — потому, что переход на язык М++ просто отодвигал эту проблему на момент когда число строк = N++ — т.е. максимум на пару лет. а следовательно — проблему не решал…

Они просто отказались от писания кода на С руками!
И они не перешли на язык M++ — потому, что переход на язык М++ просто отодвигал эту проблему на момент когда число строк = N++
Вот только не N++, а N^2 или даже N^3 при грамотном подходе. Поэтому игра все равно в большинстве случаев стоит свеч, а дальше либо ишак помет, либо падишах :)
Они просто отказались от писания кода на С руками!
C++ когда-то тоже был просто кодогенератором для C, да.
А это не важно.
Важно что С++ нет и не будет — ибо не нужен. Потому, что это не развивало индустрию а притягивало в нее лишний велосипед, раздувающий штат программистов. Развитие же наоборот сократило штат, увеличив объемы код на порядок.

То есть один из самых широкоиспользуемых языков низкоуровневого и системного программирования (в том числе в cutting-edge разработках авиа- и космической отрасли, автомобилестроении, медицинской аппаратуре, телеком-оборудовании, и ещё сотнях других сфер) вы называете "ненужным" и "велосипедом"… Как вам там живётся в вашем воображаемом мире?

Перечитал ваши комментарии и вспомнилось, как ещё в 90-х годах в универе седой препод на лекциях по ООП говорил нам, мол, зря вы сюда учиться пошли, скоро программисты будут не нужны и никто не будет писать код руками, а ПО будут разрабатывать на проблемно-ориентированных языках и CASE-технологиях… А в итоге, тот препод на пенсии, индустрия проигралась с этими специализированными недоязыками, поняла, что разработку они не упрощают и проблемы они не решают, а наоборот только добавляют новые, и выкинуло их на задворки. SpaceX с инженерами из NASA использует C++ в своих Dragon, в том числе для управления двигателями. Lockheed Martin использует C++ в авионике истребителей 5-го поколения. Nokia Networks использует C++ в ПО опорных сетей и базовых станций 5G. Список можно продолжать бесконечно.
А спрос на разработчиков на языках общего назначения тем временем стабильно растет уже десятки лет, и есть все предпосылки что этот рост будет продолжаться при нашей жизни и дальше.

А Сколько Dragon построено в SpaceX?! Если Dragon рухнет из за ошибки ПО — то ЧТО?!
Если ваш истребитель через 0-ю высоту перелетит — то ЧТО!?
5G это уже что то серьезное из вашего примера. — но все равно — откажет и ЧТО!?

В любом проекте ГДЕ-ТО всегда используется С++ — какая нибудь унылая прикладуха всегда на нем написана. Только вот, когда от кода начинают зависеть жизни миллионов людей — то C++ резко там не наблюдается, потому, что все его преимущества вдруг резко превращаются в недостатки.

То с чем ваш преподаватель игрался — стандарт индустрии. embedded софт давно уже пишется в связке Matlab-Simulink-Ascet а не в VS и тп… И программирование руками осталось лишь как трюково-кроильное (когда надо сэкономить ресурсы)…

Space-X кстати LabView как минимум использует. (9 слайд) А он тоже сам генерит код на С.
А Сколько Dragon построено в SpaceX?!
А какая разница? Они уже доказали свою надёжность и эффективность.

Если Dragon рухнет из за ошибки ПО — то ЧТО?!
Если ваш истребитель через 0-ю высоту перелетит — то ЧТО!?
5G это уже что то серьезное из вашего примера. — но все равно — откажет и ЧТО!?

Давайте я продолжу. А если кодогенератор лабвью из-за ошибки в нем сгенерит некорректный Си-код — ТО ЧТО? А если в компилятор Си из-за ошибки в нем сгенерит некорректный машинный код — ТО ЧТО? А если в топологии кристалла процессора, который будет этот машинный код исполнять будет ошибка — ТО ЧТО? А если в конструкции механизмов, которыми этот процессор будет управлять будут недочёты — ТО ЧТО?
Не надо детский сад разводить. Есть давно существующие многочисленные административные, инженерные и архитектурные меры и подходы для повышения надежности систем и минимизации логических ошибок и ошибок кодирования. И они работают.

Кстати, вы очень забавно проигнорировали мои комментарии про Ada, которые тоже суть есть язык общего назначения, но спроектирован в расчете на максимальную надёжность. За что и любим, например, Boeing.
В любом проекте ГДЕ-ТО всегда используется С++ — какая нибудь унылая прикладуха всегда на нем написана
В примерах, которые я приводил выше, ровно наоборот. Не говорите о том, о чем не знаете.
embedded софт давно уже пишется в связке Matlab-Simulink-Ascet а не в VS и тп… И программирование руками осталось лишь как трюково-кроильное
Забавная ситуация, хабраюзер рассказывает человеку, почти два десятка лет пишущего embedded-софт, в том числе для авиации и телекома, о том, какие языки там используются, а какие нет :) Вы сделали мой день, спасибо.
Вы пишете софт для единичных игрушек смешного объема — ну и какая разница что вы там используете!? да хоть в ардуиноиде пишите — никому не интересно.

А Я вам пишу о проектах с 10млн юнитов и в 2 млн строк кода в каждом. Да чтоб их руками написать — вас таких 2 непрокормимых армии нужны…

Вы пишете софт для единичных игрушек смешного объема
Телепат из вас некудышный. Ещё раз: не говорите о том, о чем ничего не знаете.
А Я вам пишу о проектах с 10млн юнитов и в 2 млн строк кода в каждом.
О, пиписькомерство началось, причем в строках автогенеренного кода. Детский сад, старшая группа.

непрокормимых
Квалифицированный специалист всегда стоит денег, да. А постоянно растущая востребованность на рынке позволяет избавить себя от работы со жлобами.
Когда эти квалифицированные специалисты фантазируют о замене таксистов автопилотами в их ближайшем светлом будущем — это нормально и всячески приветствуется. Когда же им намекают, что их самих уже давным давно заменили, причем технологиями, куда как более примитивным чем автопилот — у них возникает батхерт просто невообразимого масштаба. Как так?! А нас за что?! Мы же любимые — «всегда стоим денег» а таксисты они бесплатные.
замене таксистов автопилотами в их ближайшем светлом будущем — это нормально и всячески приветствуется
Так это логично. Вождение авто, в большинстве случаев, есть ни что иное как однообразная механическая работа, которую может выполнять практически любой человек с улицы. В отличие от инженерного дела и наук.
батхерт
Он тут, кстати, с вашей стороны очень четко наблюдается. «Тупые программисты зажрались и совсем охренели!!!11» :)
их самих уже давным давно заменили
Всякие вами упомянутые low-code и визуальные языки существуют уже десятки лет, но по-прежнему остаются очень узкоспециализированными штуками и так и не используются повсеместно, а тем временем спрос на разработчиков на языках общего назначения стабильно и активно растет в индустрии IT те же десятки лет часто даже в моменты экономических кризисов, намного опережая предложение на локальных и мировых рынках труда, и есть много обоснованных предпосылок что так будет продолжаться ещё очень и очень долго. Предлагаю спор: через 10, а потом через 20 лет встречаемся здесь же (если Хабр ещё будет существовать, либо оставьте свой емайл) и проверяем, вымерли ли программисты или же наоборот их все так же нужно в индустрии все больше и больше :)
Вождение авто, в большинстве случаев, есть ни что иное как однообразная механическая работа,


Бу го га. Вождение авто — это не однообразная механическая работа. Это решение задачи распознавания на дороге ребенка, включая случай, когда он едет на велосипеде задом наперед, сидя задницей на руле и вращая педали руками и размахивая ногами в воздухе — естественно с вероятностью в 100%. И эта задача решения не имеет ни в настоящий момент, ни через 10 лет иметь не будет.

Про с++ там где этот скачок произошел — он уже давно произошел. А там где нет — уже вряд ли не произойдет. Просто большинство embedded систем обладают конечной сложностью которая не растет исходя из самой задачи которую они выполняют и в лучшем случае там за 20лет раздуют С код на 10-20% — да и черт с ним.
Зачем на дороге распознавать именно ребёнка, когда задача стоит проще — распознать надо препятствие независимо от того человек это, животное или механизм.

Перед полиэтиленовым пакетом будете оттормаживаться так же, как перед человеком?

Ну и классика — кирпич в пакете. тормозить или нет?
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.