
Я всегда знал, что разработка для встраиваемых систем (embedded) является не тривиальным делом, но даже не представлял, насколько С++ код в реальных enterprise-проектах может быть... скажем так, перегруженным. Тем интереснее попытаться исправить хотя бы кусочек такого кода, тем более что сегодня у нас есть прилежный цифровой помощник.
Справится ли искусственный интеллект с рефакторингом кода, от которого у обычного разработчика дёргается глаз? И в чём нейросети пока ещё безоговорочно уступают человеку? Заглядывайте под кат, там много боли, костылей, D-Bus и немного С++ и однопоточной асинхронности (async single-threaded).
Это микросервисы, детка: контекст проекта
Прежде чем препарировать сам код, давайте разберёмся, где он живёт. Наш подопытный — это один из компонентов огромного open-source проекта OpenBMC (открытый код для компиляции прошивок для модулей управления серверами, десктопными системами — BMC на базе Линукс-а).
Если говорить точнее, мы попробуем разобраться с куском кода (С++ функцией) из одного из подпроектов нижнего уровня в репозитории dbus-sensors, возьмем для примера сервис HwmonTempSensor:
https://github.com/openbmc/dbus-sensors/tree/17f2fc3fe1400bf9e45c075e4864cc79afa2ed91/src/hwmon-temp
Весь этот локальный проект компилируется в один исполняемый файл — systemd-сервис, задача которого — собирать данные с аппаратных датчиков (температуры, давления, влажности, другие собирают значения тока, напряжения, другой температуры, ...) и публиковать их на системной шине D-Bus. Оттуда эти данные забирают другие сервисы (например, для отображения в Web-интерфейсе).
Звучит красиво и современно? Да, это классическая микросервисная архитектура во встраиваемых системах:
Сервис общается с внешним миром через IPC-протоколы (D-Bus).
Он работает абсолютно независимо.
Архитектура изолирована и изолирует логику работы с железом.
Всё выглядит убедительно, пока мы не спускаемся на уровень исходного кода. По факту вся логика нашего микросервиса сосредоточена вокруг одной-единственной функции. Сделать ее читаемой — значит сделать управляемым весь микросервис. Или нет?
Знакомьтесь: функция createSensors на 280 строк
Мы попытаемся провести рефакторинг функции createSensors, оригинальный код которой можно увидеть по ссылке:
Для начала я попросил ИИ-агента объяснить мне логику этой функции. Ассистент прилежно насчитал аж 12 изолированных задач, которые она выполняет! Если обобщить, то createSensors — это такой «всемогущий комбайн», который:
Получает конфигурацию датчиков от другого микросервиса (
entity-manager) асинхронно(!), но в единственном потоке.Создает или ищет соответствующие драйвера I2C устройств через
sysfsи проверяет-следит за их присутствием на шинеI2C.Сопоставляет найденные/не найденные железки с конфигурацией.
Создаёт, активирует или пересоздаёт объекты
HwmonTempSensorи регистрирует их на D-Bus.Управляет порогами (thresholds), частотой опроса, состоянием питания и логикой работы нескольких датчиков на одном физическом I2C-устройстве.
Поддерживает сразу два режима работы: полный первичный скан при старте и точечное обновление при изменении конфигурации «на лету» (через события
шины Дбас).
Нормально ли собирать все это в теле одной функции с callback-ом? Вопрос риторический. Вложенность циклов и условий if внутри этой функции доходит до 6-7 уровней (for → for/if → if → if → if...).
Что предложил ИИ-агент?
Когда я спросил ИИ: «Мне кажется, эта функция перегружена, можешь дать предложения по её рефакторингу?», он выдал вполне очевидное, но структурное заключение.
Диагноз ИИ: Функция перегружена (~280 строк в одном callback). Основные проблемы: слишком глубокая вложенность, спагетти из разнородных задач (поиск, матчинг, создание, фильтрация) и нулевая тестируемость.
Агент сформировал 7 конкретных шагов для исправления ситуации:
1. Выделение класса-сканера и декомпозиция
Вместо монолитного лямбда-выражения перенести логику в отдельную структуру SensorScanner, где каждый шаг станет изолированным приватным методом на 20-30 строк:
struct SensorScanner { SensorScanner(io, objectServer, sensors, dbusConnection, sensorsChanged, activateOnly); // Один публичный вход — точка обработки конфигурации void scan(const ManagedObjectType& configs); private: SensorConfigMap buildConfigMap(const ManagedObjectType& configs); std::vector<std::filesystem::path> findSensorPaths(); void ensureDevice(...); // Инстанцирование I2C void processPath(path); // Цикл по одному sysfs-пути std::optional<...> matchConfig(path); // Матчинг с конфигурацией };
2. Устранение дублирования при создании датчиков
В оригинальном коде логика создания HwmonTempSensor продублирована дважды (для основного датчика и для дополнительных). ИИ предложил вынести это в метод:
std::shared_ptr<HwmonTempSensor> createOrActivateSensor( const fs::path& hwmonFile, std::shared_ptr<I2CDevice>& i2cDev, ..., sensors[sensorName]);
Это сразу избавляет проект от 60 строк копипасты.
(И далее еще 5 пунктов про вынос Name1..N, структур матчинга, разделения скан/обновление, side-эффекты и ранние continue).
Результаты рефакторинга и парадокс объёма кода
Я попросил агента реализовать эти предложения в коде. В итоге рефакторинг красиво разделил «кашу» на архитектурные уровни:
void createSensors( AppContext& context, boost::container::flat_map<std::string, std::shared_ptr<HwmonTempSensor>>& sensors, const std::shared_ptr<boost::container::flat_set<std::string>>& sensorsChanged, bool activateOnly) { auto scanner = std::make_shared<SensorScanner>(context, sensors, sensorsChanged, activateOnly); scanner->run(); }
дальше можно привести код нового класса SensorScanner и отдельные его функции которые раскладывают логику исходной супер функции на уровни… Но вряд ли это кому то особо интересно, это статья не про технику рефакторинга, а про то о чем не очень принять говорить.

Графический результат рефакторинга в git-диффе выглядит забавно: было — красным, стало — зелёным, и зелёного стало заметно больше, то есть кода суммарно стало БОЛЬШЕ!
И это вполне объяснимо. Мы одну большую функцию на 250 строк разбили на 10 функций по 25 строк. Нам пришлось добавить 10 новых сигнатур методов, определить новые структуры, классы (чтобы не передавать под десяток параметров по ссылке, а кидать одну заполненную структуру). И даже несмотря на то, что агент нашёл и выпилил копипаст-блоки, объединив их, общий объем кода вырос. Страшный код просто стал... по-модному структурированным.
И вот тут мы подходим к главному откровению этого эксперимента.
Иллюзия чистого кода: почему нельзя отрефакторить одну функцию
С высоты «чистого кода» результат кажется победой: вложенность ушла, функции маленькие, структуры явные. На собеседованиях в такие проекты часто требуют уверенное владение C++20, шаблонами (Концепты, SFINAE, CTAD), понимание RAII и Structured binding.
Но знаете что? Вам ничего из этого не поможет. И этот рефакторинг проекту не поможет тоже.
Потому что нельзя сделать рефакторинг одной сколь угодно страшной С++ функции. Это сизифов труд. Ужас и перегруженность конкретной функции — это не случайный сбой/грех/ошибка/<ваш термин> уставшего программиста. Это прямое, неизбежное следствие убогости идей по организации всего проекта. Код не является первопричиной проблемы, код — это просто реализация распиаренных абстрактных концепций, которые кто-то притащил в embedded, не подумав. И микросервисы здесь — главная из них.
В чём же тут вообще состояла светлая идея? Давайте разберёмся, как устроена эта экосистема.
Идея микросервисов и однопоточной асинхронности vs Суровая реальность OpenSource
Глобальная задача всей этой совокупности консольных экзешников (микросервисов) банальна и решена в индустрии тысячи раз: найти и прочитать все доступные в системе аппаратные устройства (от Ethernet-контроллеров до мелких датчиков на I2C-шине), структурировать эту информацию и выдать её на интерактивное отображение — например, в веб-морду.
В репозитории проекта https://github.com/openbmc/dbus-sensors гордо висят Key Features:
Runtime re-configurable from d-bus (entity-manager or the like)
Isolated: each sensor type is isolated into its own daemon...
Async single-threaded: uses sdbusplus/asio bindings
Красиво? Маркетингово. А теперь посмотрим, как этот «async single-threaded» устроен изнутри на самом деле.
1. Нелепое деление и Божественный сервис
Вместо того чтобы сделать простой, понятный и монолитный алгоритм: прочитать конфигурационные JSON-файлы (желательно только для этого конкретного сервиса) -> по этим конфигурациям найти аппаратные устройства-драйверы -> активировать их и работать с ними... авторы решили поиграть в микросервисы.
Они разделили этот неделимый процесс. Теперь отдельные сервисы датчиков сами файлы конфигурации не читают. Для этого завели специальный «главный», тоже божественный сервис — entity-manager. Он читает и парсит все(!) JSON-файлы конфигураций и... просто вываливает эти данные в шину D-Bus естественно по очереди! То есть все наши асинхронные сервисы просто стоят и ждут когда будет прочитана и опубликована нужная им часть всеобщей конфигурации.
Это очень похоже на публикацию данных в Shared Memory (разделяемую память), через которую теперь работают вообще ВСЕ. Поскольку трафик огромный, а читать всё подряд никто не хочет, каждый микросервис вынужден создавать свой фильтр (по умному/или чтобы было не как у других, называется match) и отдавать его центральному сервису фильтрации. Получается один «всезнающий» божественный обработчик (это НЕ entity-manager, это еще один, никому не видный, очень-микро-сервис), который перемалывает терабайты (нет конечно только мегабайты! Но вспомните это как бы embedded!) трафика IPC взаимодействия (которое гордо назвали аппаратным словом D-Bus «шина») и раздаёт отфильтрованные крохи. Решение дико неэффективное. Но это только полбеды.
2. Главная боль: Тайм-ауты «на глаз» из-за отсутствия транзакций
Самый ад начинается, когда наш изолированный сервис пытается эти данные собрать. Ему нужна конфигурация, чтобы проверить наличие железа в указанных локациях. Сервис создаёт фильтр и начинает покорно ждать у моря погоды. entity-manager запускается и начинает выкладывать конфигурацию на D-Bus.
Но использовать эти данные нельзя, пока они не выложены полностью! А наш сервис понятия не имеет, когда entity-manager закончит вещать, ведь тот выкладывает тонны данных для всех устройств в системе постепенно-сразу. Разработчики D-Bus и концепции микросервисов в эмбеддед, видимо, никогда в жизни не слышали про транзакции и атомарные операции. Для них этой проблемы просто не существует.
Знаете, как они её решили? За счёт производительности и надежности. Раз мы не знаем, когда данные закончатся, давайте... просто подождём на тайм-ауте!
В коде это выглядит так: пока entity-manager шлёт куски конфига, наш фильтр срабатывает и постоянно сбрасывает таймер. Мы выставляем задержку в 1 секунду (filterTimer.expires_after(std::chrono::seconds(1));). Если целую секунду (пять секунд, десять, где предел?) новых данных не прилетало — ура, костыль сработал, считаем, что данные готовы и можно наконец-то вызывать нашу createSensors!
В том числе из-за убогости этой архитектурной идеи функция createSensors внутри и превратилась в ад:
Ей приходится на лету разгребать флаги
firstScan,sensorsChangedиactivateOnly, потому что данные прилетают кусками, а система как-то должна запоминать свое состояние, ее поведение не тривиально.Мы тратим драгоценное время (самый важный ресурс в эмбеддед) просто на ожидание «а вдруг там ещё что-то допишется?». Данные уже лежат, но обрабатывать их нельзя — ждём тайм-аут.
Если микропроцессор загружен и
entity-managerдопустит задержку, наш сервис проснётся по тайм-ауту раньше времени и прочитает неполные, обрубленные данные. Всё упадёт.Если данные обновятся слишком быстро, мы пропустим промежуточное значение или вообще ослепнем, тут вообще нельзя предположить чем это аукнется — это чистое UB, только не по причине особенностей языка программирования, а потому что исходная идея ущербна.
На самом деле это не единственная убогая идея глобального ентерпрайз-проекта! Из-за одной единственной нехорошей идеи С++ функция не была бы такой безнадежно ужасной. Но не будем совсем уж закапывать опен-соурс проект, все таки он компилируется и работает, хоть и неторопливо, и это огромное облегчение для тех, кто строит на этой основе свои продукты, это несомненно огромная база полезных материалов, но вот архитектурные идеи я бы не советовал копировать оттуда вслепую.
Но что я не могу не отметить, это то что вот эта хрупкая, костыльная конструкция, которая сама не понимает, в какой момент времени она выполняется, эта конструкция рекламируется в документации как великое достижение асинхронного однопоточного подхода: Async single-threaded какой-то биндинг!
В чем ИИ пока безоговорочно уступает человеку?
Когда идея оказывается не работоспособной она обрастает кучей костылей, чтобы она хотя бы выглядела работоспособной. И в конце концов сама идея теряется в этом нагромождении костылей, но никто уже и не пытается анализировать, а тем более обновить идею, это уже не безопасно — вся конструкция обвалится! Поэтому выбора нет, только подставлять все новые костыли выдавая это за развитие проекта.
И вот тут мы возвращаемся к нашему ИИ-агенту. Нейросеть — потрясающий, прилежный инструмент. Она идеально разложила спагетти-код функции по отдельным тарелочкам-методам, создала структуры, убрала дублирование. Код стал выглядеть цивилизованно (я думаю вы поверите мне на слово!, хотя нет ничего проще скачать этот проект и проверить с вашим кодовым агентом).
Но ИИ совершенно не способен понять, что он рефакторит костыль. (дописано: или способен, но ему все равно?)
Нейросеть оптимизирует текст программы, а не инженерное решение. Она послушно причесала процедурный хаос, обернула его в красивую ООП-обёртку, но фундаментально логика осталась той же тяжеловесной костыльной системой, завязанной на убогую архитектуру межпроцессного взаимодействия. ИИ никогда не включит «стоп-кран» и не скажет: «Слушай, само это деление на EM и демоны датчиков — нелепость, давай выкинем этот D-Bus цирк и напишем нормальный монолитный парсинг» или не монолитный, а например библиотечный, если надо сделаем динамически загружаемые конфиги, но только там где это надо и только тогда когда это действительно надо. Давай разделим файлы конфигурации на уровни! Хотя бы на два! Общий конфиг, который нужен всем или почти всем и конфиги нижнего уровня, которые нужны конкретным сервисам. На самом деле это действительно не простая задача, как это правильно реализовать, но чтобы решить эту задачу ее для начала надо хотя бы увидеть-сформулировать, а не пытаться пробить лбом стену там, где написано «Async single-threaded».
ИИ никогда не включит «стоп-кран» и не скажет … Хотя, наверно, скажет! Скажет если вы напрямую его об этом спросите и предоставите достаточно контекста чтобы все проанализировать (тоже дописано).
Вывод
Нейросети сегодня — это классный инструмент для локального марафета. Но если архитектурная идея проекта изначально ущербна, никакой ИИ и никакой C++20 не сделают код хорошим. Они просто сделают ваши костыли более структурированными, чистыми и объектно-ориентированными или функционально-ориентированными, кому как нравится.
Хотя… нейросети завтра могут быть более обученными и возможно смогут проводить более серьезный анализ не только самих данных но и того сколько ей нужно данных чтобы выдать адекватный поставленной задаче результат… запрашивать дополнительные данные они уже умеют...
Архитектурное видение, критический анализ жизнеспособности идей и понимание предметной области по-прежнему остаются строго за человеком, но если правильно сформулировать предметный вопрос, нейросеть и в этом тоже очень может помочь.
А как вы относитесь к микросервисам и оверинжинирингу в embedded-разработке? Вы когда нибудь доходили до уровня осознания бредовости изначальной идеи, на которой построен проект?
Комментарии (18)

eao197
12.10.2026 03:51После прочтения этого “плача Ярославны” у меня два вопроса:
хоспади, зачем это было написано?
хоспади, зачем я это все читал?
Человек увидел в реальном мире говнокод (еще и не самый страшный, скажем прямо) и побежал вайбкодить статью о том, что он нашел говнокод. И все.
Ладно бы показал, как этот говнокод привести в приличный вид и выиграть по всем параметрам. Так ведь нет. Просто поплакал о том, что говнокод есть, а ИИ не в состоянии пока сделать из говна конфетку.
Что до претензий к архитектуре, принятой в openBMC, то вот у авторов были свои идеи. Они их воплотили в жизнь. Видимо, им нужно было. Если у вас есть свои идеи, как вам кажется более правильные, то сделайте по-своему, выложите в OpenSource. Уверен, очень быстро найдутся другие вайб-кодеры, которые найдут в ваших архитектурных решениях фатальный недостаток, а то и не один.

rukhi7 Автор
12.10.2026 03:51После прочтения этого “плача Ярославны”
Человек увидел в реальном мире говнокод (еще и не самый страшный, скажем прямо)
Может надо было назвать это "Зульфия открывает глаза", а не “плач Ярославны” ?
Благодарим за адекватную оценку, а то все: значимые проекты в OpenSource (вроде GCC, LLVM, OpenJDK, LibreOffice и т.д.) пишутся профессионалами

eao197
12.10.2026 03:51Может надо было назвать это “Зульфия открывает глаза”, а не “плач Ярославны” ?
Надо было определиться с тем, о чем статья:
о том, что вы считаете ошибкой проектирования в проекте OpenBMC;
о том, что вы считаете говнокодом в конкретном месте проекта OpenBMC и способах его исправления;
о том, что вы можете сделать с ИИ для рефакторинга говнокода в C++.
Каждая из этих тем тянет на отдельную статью, а вы все смешали в одном флаконе и получилось ничуть не лучше того C++ного фрагмента, к которому решили доколупаться.
Благодарим за адекватную оценку, а то все: значимые проекты в OpenSource (вроде GCC, LLVM, OpenJDK, LibreOffice и т.д.) пишутся профессионалами
Именно так. И если вы живете в другой вселенной, где это не так, то может вам и продолжать там жить? А то ведь здесь вас ждут удивительные открытия, например, что “профессиональный” вовсе не означает “максимально качественный” (да даже и “качественный”).

rukhi7 Автор
12.10.2026 03:51о том, что вы считаете ошибкой проектирования в проекте OpenBMC;
Вы хотите сказать вы это (например) не поняли из статьи? Ну тогда я вам никак помочь не смогу, к сожалению.

eao197
12.10.2026 03:51Вы хотите сказать вы это (например) не поняли из статьи?
Я хочу сказать, что если этот пункт и был главной темой статьи, то не нужно было туда впихивать еще и рассуждения о большом объеме одного C++ного метода, и о том, что может и чего не может ИИ.
И если эти мои слова для вас так же непонятны, как и предыдущие, то расшифрую: вы доколупались до C++ного метода в 250+ строк, но сами в своей статье поступили точно так же: напихали в одно место всякого разного, что, по хорошему, следовало разбить на разные статьи. Т.е. вы своей статье не смогли в декомпозицию, но доколупываетесь до кода, в котором в декомпозицию не смогли точно так же.

rukhi7 Автор
12.10.2026 03:51то расшифрую: вы доколупались до C++ного метода в 250+ строк, но сами в своей статье поступили точно так же ...
Что ж вы так за "C++ный метод в 250+ строк" переживаете? Вы тоже такие пишите? Я же вам не запрещаю такие писать!
А статью я, к сожалению, компиляцией проверить не могу. Статья должна заставлять думать, в первую очередь, по моему. Ответов на все вопросы у меня конечно нет, хотя на некоторые я, определенно, ответить могу, если вы дадите себе труд их сформулировать. Кстати, некоторые вопросы, достаточно, всего лишь попытаться сформулировать, и окажется что ответ очевиден.

eao197
12.10.2026 03:51Ответов на все вопросы у меня конечно нет, хотя на некоторые я, определенно, ответить могу, если вы дадите себе труд их сформулировать.
Ну вы бы сперва читать то, что вам пишут в комментариях, научились бы. Может тогда и уже сформулированные вопросы там разглядеть сможете.

rukhi7 Автор
12.10.2026 03:51хоспади, зачем я это все читал?
ну это вряд ли ко мне вопрос :) ! Вам видимо действительно повредило и вы не можете теперь без слез глядеть на свой sobjectizer, извините.
Но я попробую вас обнадежить, после известных 7 стадий иногда наступает неизвестная восьмая! Она называется креативность. Есть надежда что потом захочется что-то поменять и, действительно, получаться станет лучше, с учетом пройденного.

eao197
12.10.2026 03:51ну это вряд ли ко мне вопрос
Вы для себя на первый вопрос ответьте.
вы не можете теперь без слез глядеть на свой sobjectizer
Я вот хз зачем вы этот инструмент упоминаете в контексте оценок вашей ИИ графомании. Но как раз в SO-5 проблем с асинхронной работой в одном потоке нет от слова совсем. Там даже специальный режим есть, чтобы все работало строго в одном потоке.

rukhi7 Автор
12.10.2026 03:51на первый вопрос:
хоспади, зачем это было написано?
раз уж вы не постеснялись о нем вспомнить, ответ такой:
Не вам распоряжаться кто какие себе вопросы должен задавать, не надо думать что вы вправе распоряжаться чужими мыслями, не надо корчить из себя что-то вроде Наполеона, властителя дум.

eao197
12.10.2026 03:51не надо корчить из себя что-то вроде Наполеона, властителя дум
Может тогда вы перестанете строить из себя хз кого и попробуете кратко ответить самому себе на вопрос “зачем эта статья была написана”?
Я вот прочитал и не понял.
Если вас возмутила функция на 250+ строк – это одно. Но бывает еще и не такое. Во-первых, ничего страшного. Во-вторых, кроме констатации сего факта вы не дали никаких рекомендаций по исправлению.
Если вас возмутили проектные решения в OpenBMC – то это совсем другое. Ну возмутили и возмутили. Дальше что? Вы предлагаете не пользоваться OpenBMC? Вы предлагаете что-то переделать в OpenBMC? Какой сухой остаток из вашего возмущения?
Вы удручены тем, что ИИ не может хорошо отрефакторить плохой C++ный код? Ну бывает, и что?
Повторюсь: вы смешали в кучу разные аспекты и непонятно какие выводы читатель должен был сделать из вашей статьи. Поэтому у меня, как у читателя вашего совместного с ИИ творчества, возникает вопрос “нафига и, главное, зачем?” Что читатель, вроде меня, должен был вынести из этого всего потока?

rukhi7 Автор
12.10.2026 03:51Во-вторых, кроме констатации сего факта вы не дали никаких рекомендаций по исправлению.
Видимо надо специально для вас отдельно скопировать:
Слушай, само это деление на EM и демоны датчиков — нелепость, давай выкинем этот D-Bus цирк и напишем нормальный монолитный парсинг» или не монолитный, а например библиотечный, если надо сделаем динамически загружаемые конфиги, но только там где это надо и только тогда когда это действительно надо. Давай разделим файлы конфигурации на уровни! Хотя бы на два! Общий конфиг, который нужен всем или почти всем и конфиги нижнего уровня, которые нужны конкретным сервисам. На самом деле это действительно не простая задача, как это правильно реализовать, но чтобы решить эту задачу ее для начала надо хотя бы увидеть-сформулировать, а не пытаться пробить лбом стену там, где написано «Async single-threaded».
Да это не готовое решение, но это как раз рекомендации.
Готовое решение мне пока не позволено публиковать, оно не только мне принадлежит.
Ну и в комментариях я вам тоже уже написал выше:
Статья должна заставлять думать, в первую очередь, по моему.
Читайте внимательнее! Перестаньте нервничать, что ли.

eao197
12.10.2026 03:51Да это не готовое решение, но это как раз рекомендации.
Для кого это рекомендации? Для авторов OpenBMC?
Готовое решение мне пока не позволено публиковать, оно не только мне принадлежит.
Т.е. у вас “есть такие приборы, но мы их вам не”, правильно понял?
Перестаньте нервничать, что ли.
У вас кроме графомании еще и потуги в диагнозы по Интернету?

rukhi7 Автор
12.10.2026 03:51Для кого это рекомендации? Для авторов OpenBMC?
да нет! У нас свои задачи! Задачи авторов OpenBMC мы не знаем, какое нам до них дело! Странный вопрос вообще-то! Вы считаете что можно работать только чтобы порадовать авторов OpenBMC?
правильно понял?
В точку!
У вас кроме графомании еще и потуги в диагнозы по Интернету?
ну это лучше, чем давать советы о чем вы сами с собой должны поговорить, согласитесь? Но это был не диагноз, а предположение, к слову сказать. Но мне, почему то кажется, что вы опять чего то напугались, не обессудьте :).

vadimr
12.10.2026 03:51Ну как бы когда в голове Бейсик (в плохом смысле), то это надолго. Такой корявый код, состоящий из последовательности мутных присваиваний, получается, когда программист сам чётко не понимает, что он хочет сделать, и решает разбираться с отдельными неприятностями по мере поступления. Нейросеть тут не поможет никак, поскольку она сама действует примерно так же.

Siemargl
12.10.2026 03:51Как говно не рефакторь....
Возможно, многие эмбедщики правы, что отказываются от С++ - на чистом С так не напишешь.
bkisonka
Вот как нейросеть видит данный проект при анализе исходников (публикую только вывод, там большая портянка):
Сильные стороны:
Архитектура микросервисов на локальной шине — образцовая: IDL-first контракты, service discovery (mapper), подменяемые реализации, нулевая связанность демонов между собой. Для встраиваемого проекта это очень высокий уровень инженерной культуры.
Декларативность: платформа = JSON-конфиги entity-manager + выбор packagegroup-фич; логика последовательностей = systemd-таргеты. Порог входа для поддержки «ещё одной платы» низкий.
Безопасность продумана системно: разделение привилегий по D-Bus-политикам, mTLS, Redfish-привилегии, hardened-флаги компиляции, отдельные пользователи для демонов.
Живой процесс разработки: Gerrit + Jenkins CI, обязательные тесты и рецензии.
Слабые стороны и компромиссы:
Сложность кросс-репозиторной разработки: добавить одну фичу часто затрагивает 3–4 репозитория (YAML интерфейса → codegen → демон → Yocto-рецепт) с синхронизацией через Gerrit. Кривая обучения крута (нужно знать Yocto, D-Bus, корутины C++20, meson).
D-Bus брокер — единая точка отказа: при падении шины система слепнет (частично смягчено fail-monitor и рестартами systemd, но это узкое место по конструкции).
Ресурсная цена: модель «много мелких процессов» и Boost в bmcweb тяжеловаты для BMC с 128–256 МБ RAM; bmcweb на шаблонах C++20 ещё и очень долго компилируется.
Следы встраиваемости ощущаются буквально: пути конфигов hwmon повторяют devicetree и превышают 260 символов — при клонировании на Windows мне пришлось включать
core.longpaths, checkout по умолчанию падает. Это не «баг», но показывает, что вне Linux с проектом работать тяжело.Итог. OpenBMC — зрелый, строго модульный проект уровня инфраструктурного ПО: D-Bus играет роль, которую в облаках играют REST/gRPC, а systemd — роль оркестратора вроде Kubernetes (в миниатюре). Архитектура рассчитана на долгий жизненный цикл и массовое многовендорное переиспользование, и плата за это — высокая сложность разработки и требовательность к ресурсам целевой платформы.
По моему адекватная оценка.
rukhi7 Автор
вот как это так получается одновременно и:
и:
Очень интересно!