Как стать автором
Обновить
7
0
Владимир @volodyaleo

Программист микроконтроллеров

Отправить сообщение

Ограниченная применимость CLI. Это, конечно, супер, что в конкретном проекте с мягкими условиями получилось использовать. Но:

1) Я всегда могу подключить программатор и одним тыком залить тесты и увидеть результаты прогона в логах. Даже могу по целям разным разложить и лить и запускать то одни, то все.

2) Не везде есть столько памяти чтобы и тесты и прошивку (масс прод всегда экономит деньги)

3) Всегда лучше когда тесты никто не запускает руками, а они сами запускаются на стенде когда коммит попадает в репозиторий (да, для этого кли не нужно, все автоматически через CI/CD делается).

Я Вам про автоматизацию и нормальные процессы, Вы мне про то как удобно подключить провода, прошить, открыть консоль и писать команду запуска)

Зачем CLI чтобы вызывать модульные тесты? О_о. Зашил и они сами запустились. Потом список прошедших и заваленных в логи капнут. Так можно в тест раннерее даже спокойно крутить написав мини bash скрипт который шьет все тесты в одном бинаре, вызывает ребут, забирает логи и руинит пайп если тесты не пройдены (простым grep-ом искать "All tests passed")

Cli выглядит как ручной подход к отладке и тестам. Причем странным т.к. приёмочное тестирование должно осуществляться по сценариям использования с релизной конфигурацией железа и софта.

Если есть модульные и интеграционные тесты, CI/CD то CLI бесполезен.

Если прочитать мой комментарий и описанный подход, то "процессор не будет тормозить". В релизе ни cli ни логи не нужны. Только на этапе тестирования (и то не acceptance) и диагностики. А на счёт Ниагарского водопада - логировать надо то, что действительно нужно, а не каждый вызов функции и что попало.

Получился кодогенератор. Если на c++ тоже можно написать, но по времени будет значительно дороже (flex-bison явно выглядит сложнее).

Но генерировать этим генератором можно и c и c++ код и доку т.к. там под капотом шаблонизатор jinja2.

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

CLI не просто требует памяти, а еще и не везде влезет. Это занимает место в буферах и ROM. И вносит задержки.

Выглядит прикольно, но. Зачастую вместо него можно логи на одну TX ножку в debug сборке тащить, а RX не инициализировать. И настроить логгер который можно переключать при компиляции дефайнами: включать-выключать для модуля или уровень подробности менять.

Далее два подхода к тестам:

1) Модульные тесты, которые на железе пускаются с включенными логами и проверяются куски кода по сценариям. Тут можно наловить урожай достаточный чтобы дальше вручную не проверять много всего.

2) Интеграционные - собирать стенд, который умеет продёргивать ножки или по сети команды бросать и собирать логи. Цеплять такое можно к CI/CD (никто из команды не уронит код на мастере). Если макетировать на отладках, там уже часто есть board controller к которому в тестах можно цепляться по тому же CLI и ножки переключать. Сами тесты на каком-нибудь питоне можно писать наподключив кучу библиотек, которые умеют все что надо делать. И сами производители чипов для сетевых протоколов специфичных не редко дают библиотеки на питоне.

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

Звучит как будто на тесты уйдет прилично времени. И да и нет. CLI написать тоже время - и каждый раз поддерживать, лечить при обновках. Тест написать один раз - и он будет автоматически проверяться каждый запуск. Не надо ничего каждый раз отлаживать вручную.

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

Вы не устали? Имеет смысл сходить на курсы "аджайл гуглинг инженер". Тогда можно минут за 30 будет выяснить что за расширения файлов. Например, тогда не будет казаться странным что есть файлы *.cmake и они используются внезапно cmake-утилитой. Или что её можно заставить генерировать из шаблона (внезапно файлы с расширением *.in) настройки или код.

Вы потратили на комментарии на хабре минимум пару дней за которые можно было документацию прочитать всю. Найти nrf connect плагин в vscode который сам всё делает. Или элементарно погуглить.

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

Посмотрите на ядро Linux и с удивлением половину инструментов можно найти. nRF SDK для ble mesh когда-то был, там тоже был cmake.

P.S. под nrf нордик выпустили несколько тулов которые снимают с программиста необходимости знаний тулов. Для использования в сыром виде без ncs sdk, для STM или др. чипов они вообще поставляют докер контейнер который можно и в ci использовать или в vscode через remote development (docker) плагин... Только юзера нерутового добавить и за полчаса готово всё.

PS2: не надо хабр комменты использовать как stack overflow. Для технической поддержки можно прямо в zephyr создать issue или написать на форуме Nordic semiconductor.

Возможно тут поможет внимательное чтение документации и чтение внимательное ошибок в консоли. Ибо у меня собиралось в разные папки, и проект с sdk хранил отдельно. И разнообразие было выбора куда собирать (debug, release отдельно в разные папки). И артефакты вытаскивать не было проблем. Ну и с git никаких проблем.

1) артефакты можно в ci/cd указывать в любую папку. И ничего не мешает в своем cmakelists добавить команду переноса куда хочешь на postbuild. Или при вызове cmake указать не только сурс, но и билд фолдер, чтобы именно туда собирать hex-ы.

2) в любой папке за пределами sdk можно свои проекты делать. Только zephyr_base надо определить свой

3) был свой репозиторий и не прощались

Кстати, я west не пользовал. Он всё равно тот же самый cmake дрыгает. Сразу брал cmake и надо было пару переменный в environment выставить. Вид тулчейна и еще что-то. Так как-то быстро раскаталось. И в cmakelists свой надо было заинклудить уже их sdk. Сам SDK сабмодулем в папку external добавил.

ZEPHYR_BASE не помню, толи в своём cmakelists. Толи в environment.

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

Некоторые вещи взяли из linux. Например, Kconfig, DeviceTree. Это было вполне разумно с учётом того, что из SDK очень большой.

Cmake тоже уже почти стандарт. Причем генерируют Ninja, который быстрее make работает.

Допом они overlay концепцию красиво реализовали, в моем проекте смог поддержать несколько разных плат.

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

Думаю подобного большого размера система без автоматизаций на мейкфайлах рассыпалась бы или вникать было бы гораздо сложнее. Однако по опыту написания проектов - дело шло очень быстро. И драйвера подключались/отключались быстро. Но сначала пришлось повникать в DeviceTree.

Мой личный опыт был - очень быстро раскатался не самый простой проект. Потому, что драйвера были готовые. Файловая система итд. В том числе помогла либа для обмена сообщениями между чипами. В сравнении с другими sdk гораздо быстрее. Меньше велосипедов и не надо было "свои очереди сообщений" делать, примитивы синхронизации или портировать из раза в раз тонну инструментов... Тестовый фреймворк тоже вложен. Можно некоторые тесты хоть на борде раскатать хоть на рабочем компе с эмуляцией драйверов.

Если у функции название адекватное и написана нормально, то не надо ничего рыскать чтобы понять что функция делает. А босс-функции невлезающие в экран разбирать иногда неделями надо. Когда только автор функции знает как она работает - это кошмар для коллег.

Разбухшие заголовочные файлы говорят о ужасной разбивке кода на модули.

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

К тому же всё в одной функции делать зачастую бессмысленно. Либо компилятор сам заинлайнит либо можно заставить.

Я понимаю, что си не без грешка. Но он и применяется сейчас в основном в эмбеддед. И да, рядышком улеплены везде ассемблерные вставки обычно в sdk так как работа в эмбеддед касается железа напрямую. Зачастую больше кода там "unsafe" так как приходится обращаться напрямую к регистрам, аппаратной части, DMA итд. Там и аут оф баунд используют на структурах во благо (в парсере протоколов кастуют буфер на структуру с массивом единичной длинны и вкладывают в структуру байтик длины, не безопасно, но видал такое часто...). Поэтому аргументы кажутся слабыми ибо рассматривался язык как высокоуровневый. Но это давно не так.

В мире эмбеддед еще есть свои ограничения по памяти, например 1кб под ROM. Есть специфические требования, например DMA не умеет работать с ROM и вызовет хардфолт. Иногда требуется вообще к какому-нибудь адресу пригвоздить данные. Я не пробовал rust, но подозреваю, что в тех местах, где меня надо "спасать", он не поможет. Ибо эмбедеры обычно берут готовые абстракции для очередей и мем пулов. Выключают heap. И работают на стат буферах, где ошибиться довольно сложно... Таблицу векторов прерываний на си пишут или asm, там вообще функции строго по адресам должны быть. Пишут стартап файлы свои, чтобы из своих секций загружать данные правильно.

В сухом итоге- из проекта безопасного кода не очень много. И он обычно просто дёргает библиотеки и обертки, там уже сложно косякнуть.

А spectre не страшен, если ты экзекьюшен с RAM выключил и отключил debug интерфейс (аппаратная защита).

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

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

Не думаю, что другие языки не используют регистры и RAM. Соответственно это применимо ко всем языкам. Чем тогда именно си плох? Если в rust (да любой язык вместо) создать переменную строку, потом сравнить с другой, где строки будут?

И сколько байт от пароля окажется в регистре - детали имплементации. Может один байт. В других языках как будет дело?

Нарушение секьюрити в другом компоненте - также при чем тут си? В других языках такого нет? Например в Rust подключенная либа с unsafe (любой язык кроме rust также)

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

8 символов влезет, но если пользователь 9 впишет? И куда терминальный символ делся? Как быть с фактом, что пароль в регистре ничего не дает? При свитче контекста ос должен восстанавливаться контекст другой задачи автоматом операционной системой. Пароль в регистре что-то может дать, если подключился дебаггером и бог ассемблере, который может весь фотошоп отладить внимательно смотря в регистры и аллокации. Но от такого вообще ничего не спасёт.

На счет "пароль останется в регистре процессора". Размер регистра не позволит пароль там хранить из-за размера регистров. Абсурд в квадрате.

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

Человеку, допустившему такие ошибки, ничего не помешает при портировании кода на Rust просто взять и затолкать в блок unsafe всё (взяв первую ссылку которая бы посоветовала это сделать и не дочитать). Если следовать той же логике - rust тоже дает себе в ногу стрелять и поэтому надо заменить. + большой пласт ошибок с дедлоками и конкаренси никак не наловишь.

Если интересно писать на си безопасно, обычно применяют базовые вещи - юнит тесты, и санитайзеры: undefined behavior, address sanitizer, memory sanitizer, thread sanitizer. Однако если стиль кода хороший, чаще всего ловятся логические ошибки, от которых ни один язык программирования не сможет защитить, только тестирование. Также существуют стат анализаторы которые большой пласт ошибок ловят.

Аргументация слабая и если рандомно стучать по кнопкам явно не следует ожидать чего-то хорошего. Раньше автор умрёт от старости чем си.

П.С. я не против раст, а против слабых аргументов.

Авторы попытались привнести следующие улучшения:

1) они построили микроядерную архитектуру

2) интересная концепция все есть url

3) они уделили особое внимание стабильности, безопасности (rust позиционирует себя как более безопасный язык чем си)

4) подсистема драйверов работает в пользовательском пространстве внутри песочницы (еще жирный плюс к безопасности)

В принципе довольно обоснованно попробовать все эти вещи. Другое дело развитие, совместимость и популярность. Надеюсь, у ребят получатся задумки. Но во всяком случае в академическом плане очень интересно.

1

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность