Михайлов Алексей Анатольевич @MinimumLaw
Linux Kernel, Bare metal, Embedded developer
Information
- Rating
- 2,444-th
- Location
- Пушкин, Санкт-Петербург и область, Россия
- Date of birth
- Registered
- Activity
Specialization
Embedded Software Engineer, Software Architect
Senior
From 350,000 ₽
Замечу лишь, что странно. И с необходимостью каким-то образом доказывать этот момент я никогда не сталкивался. Но вопрос скоре к функции doSomethingElse(). Должна она менять направление, не должна, и в каком оно должно оставаться по выходу. Исключительно от этого зависит правильность или неправильность предложенного кода. Универсальный вариант, впрочем, тоже известен:
Впрочем, от ситуации когда doSomethingElse() может вызываться и из обработчика прерываний он не спасет. Но опять же — вопрос скорее в логике работы.
А чем алгоритм работы хуже (или непонятнее) чем бизнес-логика? Давайте посмотрим на определения:
Попробуем получить настолько же внятные расшифровки для «бизнес-логики»? Сначала отметем все сугубо коммерцеское от слова бизнес, вспомнив, наконец, что с английского это всего-то «дело». Потом так-же пошерстим логику, под которую последовательность и взаимосвязь действий тоже напрямую не подходят…
Впрочем, ну пусть будет бизнес-логика. Я же перед программированием все равно алгоритмы прорисую. Хотя бы в голове и для себя персонально.
Дык я и не хочу сводить дискуссию к любым проявлениям священной войны. Лишнее это. Поэтому давайте ограничимся тем, что:
Впрочем, не могу не признать Вашу правоту. MISRA C++ я, к стыду своему, даже не смотрел. Пожалуй стоит наверстать.
P.S.
Единственный момент — реле дороже проводников, но у него три четких состояния включено, выключено и неисправно. Его любят именно за это.
Я не понимаю до конца вопроса, потому простите — отвечу как понимаю.
Контроллеры, как правило, однопроцессорные и однопоточные решения. В варианте голого железа эффект конкурирования за ресурсы может возникнуть либо между обработчиками прерываний (если разрешена вложенная обработка), любо между прерыванием и фоном. Таким образом вопрос доказательства сводится к алгоритму реализации. Если фон позволяет себе не задумываясь писать в пин, направление которого меняет обработчик (или наоборот, что совсем не принципиально), то это проблема алгоритма решения задачи. А такие проблемы всегда должны решаться заменой алгоритма и никак иначе.
Если же поверх железки работает что-то, что позволяет «наплодить» потоки, то контроль доступа к ресурсам стоит доверить именно этой среде. Потому как любые попытки использовать для этих целей специфические инструкции могут весьма существенно мешать планировщику, а без них не будет гарантии атомарности.
Но повторюсь, я не уверен что вопрос понял правильно.
Я предпочитаю «доказывать» сертификационными испытаниями итоговой железки. При чем меня всегда интересует не момент работает/не работает, а на каком превышении интенсивности событий от рассчетного (заданного в ТЗ) начинается пропадение данных. И как ведет себя железка, имеющая мусор по одному или нескольким (всем) входным каналам. Не будет ли перезапусков. Больше того, как правило я прошу поломать мне память. Есть у нас некоторые, хм, воздействия, которые гарантированно вносят сбои в SRAM'ы. Всегда стремимся к том, чтоб после окончания воздействия помехи был максимум один перезапуск. С таким программно бороться точно не получится.
Но еще раз — я не настаиваю на том, что всего этого можно достичь только связкой pure C + Assembler. Просто мне проще именно так.
И да, простите, но бизнес-логика… Во встраиваемых системах? Нет, конечно, четкие и понятные алгоритмы работы, наверное, частный случай той самой бизнес-логики. Но мне все же привычнее, когда алгоритмы называются алгоритмами. А бизнес-процессы — это смежная область.
Да и в целом — меня коробит сама постановка вопроса в стиле «как защититься от выставления логического уровня на пине, сконфигурированном как вход?» Это вообще что такое? Если реализация позволяет такое, надо срочно менять реализацию а не колдовать с конфигурацией пинов. Или я что-то не так понял?
Смотрите как быстро мы скатываемся в политику. На ровном вроде бы месте.
Еще раз — мир большой. Раз какие-то решения возникают, значит в них есть необходимость и потребность. Я ничего не имею против плюсов, раста, питона, да того же бедуиского языка от Arduino и много чего еще. И даже во встраиваемых системах.
Но сильно хочу, чтоб системы перевода стрелок и управление светофорами на железной дороге оставались аналоговым, на поляризованных реле с несимметричным отказом. А код для ЭБУ автомобиля был не просто написан на C, но проходил сертификацию по MISRA. А в самолетах и того круче. И свои код я хочу писать так, чтоб «как для самолета», в самом крайнем случае «как для автомобиля». И язык, на котором работаю, выбираю исключительно из этих соображений. Возможно, на других языках можно не хуже. Но моим заказчикам нужно вчера. И даже если нужно было бы завтра заменить многолетний опыт работы с одним языком неглубоким знакомством с другим — решение крайне сомнительное.
Собственно все. Еще раз — пусть расцветают сто цветов, пусть соперничают сто школ. Но не надо меня силком тащить в светлое завтра. По мере надобности и интереса я сам все осилю. Как в свое время осилил плюсы, как сейчас разбираюсь с Rust. Но пока мнение осталось тем же — pure C оптимум по соотношению сложности к гибкости для всего, что «непосредственно шуршит по регистрам»
Вот именно это «если» меня и не устраивает. Я знаю чуть ли не с точностью до такта сколько времени выполняется та или иная часть программы. Я знаю максимальную интенсивность событий, на которую железка сможет прореагировать, я знаю как она поведет себя в случае перекосов. Увы, я всего этого не знаю, если есть динамическая память.
Да, еще раз — сейчас уже не приходится «ксорить указатели» ради экономии пары байт. Но я-то еще помню как и зачем это делается. И если теперь не надо экономит пару байт, это еще не говорит о том, что можно потратить сотню-другую тактов на то, что просто поиметь буфер для записи. Ибо такты тоже не бесконечны, а вместе с ростом производительности и объемов памяти у микроконтроллеров растут и хотелки, которые на них вешаются. И тут начинается… FreeRTOS или ее аналоги с ее системным таймером и временем реакции кратном системному таймеру, или голое железо с логикой внутри обработчиков прерываний и перекидыванием длительных кусков кода между разными обработчики и тупой сон в фоне.
Ну, или бьем комаров атомными бомбами (а чего мелочиться — они нынче сильно подешевели). И подумаешь на каждого комарика по бомбе — мы ж не на нищебродов работаем… Впрочем, простите, накипело… Давайте считать, что весь этот абзац ограничен тегом «сарказм»
Я же не говорю что здесь хоть что-нибудь "не так". Как раз наоборот — здесь всё довольно красиво. Во всяком случае в рамках обозначенного объёма.
Давайте я озвучу свое понимание проблематики. Мне крайне редко (чтоб не сказать никогда) встречались системщики, которые находились бы ближе к прикладникам, нежели к схемотехникам. А те, ко то из нас, которые "от железа" к языкам уровня выше C относятся очень настороженно. Если хотите, то могу и причину назвать — все они так и норовят по каждому чиху использовать динамическое выделение памяти. А это затраты времени, и, что хуже снижение надёжности и отказоустойчивости кода. Отчасти поэтому мы и не любим работать парой, а ещё хуже тройкой над одним проектом. У каждого свои приоритеты и дольше будет договориться как именно мы дружить будем, чем одному написать.
Дело не в том, что мы ленивы и не способны выучить другой язык. Дело в том, что у нас аж две священных коровы: скорость и надёжность. Не можем мы их резать в угоду удобства, а тем паче моды. Для нас и C высоковат. Очень часто приходится бороться с его неоправданными оптимизациями. Или спускаться на уровень ниже, там где волшебник C странно трактуется директивы register. А наследование мы и на C можем. Быстро и в достаточном объеме. Вон CodeRush рядом пример приводил. Да и весь драйверный код Linux тому хорошее подтверждение.
Но вернёмся к статье. По мне тут вилочка отрисовывается. Одно дело, когда у автора глобальная задача требует плюсов и ему этот "котел" роднее и известные. Не вопрос. Сел, продумал, написал — просто красавец. И другое, когда над этой "отвязкой от железок" окажется прикладник, привыкший к богатству ресурсов ПК.
Но современный мир сильно отличается от того, с которого я начинал. Сотни мегагерц тактов и сотни килобайт оперативки, мегабайты флеш-памяти. В принципе, добавь MMU и контроллером оно уже не будет. Поэтому стоит воспринимать меня как старого брюзгу. Возможно за подобными решениями будущее. Вон та же Apple давно и довольно успешно переписала ядро BSD на плюсах. По мне весьма недурно получилось. Так что поживем — увидим. В конце концов когда я начинал ряд старичков так же брюзжал "зачем здесь контроллер и программа — тремя логическими микросхемами и пятком RC-цепочек обойдёмся".
Вступлюсь, пожалуй, за коллегу. Хотя и не очень согласен с его постановкой вопроса.
Дело ведь не в скобочках. И непривычная семантика легко становится привычной. Дело в другом. Хорошо, допустим уровень абстракции портов получился красивым. Оно действительно так — тут ничего не скажу. Но порты одна из самых простых вещей. А как быть с остальной периферией? И ладно бы только с периферией.
Мне кажется, что такой подход выпускает джина. Если раньше приходилось воевать на привычном поле битов и адресов, то теперь мы воюем на поле конструкторов и наследования. А это уже поле непривычное, а в случае с контроллером ещё и довольно сложно поддающееся отладке. Простого дампа памяти наверняка окажется мало.
Соответственно и применение. Или весь верхний код можно отладить и отмакетировать на ПК, или системщик просто гений, или он (системщик) делит поляну на свою и прикладников. Первые проекты довольно редкие, гения мы выносим за скобки — тут свои правила, а последний вариант грозит проблемами с завершением проекта. Ибо "в одну упряжку коня и трепетную лань" даром обычно не проходит.
И да, все написанное только мое мнение. Я совсем не утверждаю что так нельзя или неправильно. Мир большой и каждому решению найдется свое применение.
Однако, мне не интересен разговорный язык. Вот честно — я не говорю, я пишу. Списки рассылки, форумы и прочие площадки. Говорю я только на родном языке. Да, конечно, я динозавр. Но все же.
При таком раскладе акцентироваться на произношении, IMHO, смысла нет. А вот на чтении — очень даже. К счастью, в подавляющем большинстве случаев «тематический» иностранный оказывается вполне международным (и не важно, какая именно область знаний задействована: математика, биология, физика, химия, политика или IT). А вот «языковой перчик» — как раз очень приятно и полезно черпать из книг. Начиная с детских, дажее подростковых и дальше вплоть до бульварного чтива. За одно и словарный запас пополняется. И, конечно, согласен — даже здесь важен не столько перевод, сколько контекст. Не надо лезть в словарь и пытаться переводить пословно — важно уловить суть. Ну, и некоторые слова подсмотреть в словаре.
Да, наверное это не совсем то, с чем приходится иметь дело вам. И, пожалуй соглашусь — в некотором смысле сурогатное владение языком.
Но, черт возьми, это инженерный подход. Ровно столько, сколько надо и не буквой больше.
С другой стороны, а скажите — то, что реализовано в части того же SecureBoot не кажется Вам некоторой чужеродной надстройкой. По мне так тут как раз стык безопасности и секретности. Секретность как в первую очередь следствие потенциальной небезопасности написанного кода, а во вторую защиты коммерческих интересов. Впрочем, что первично что вторично — вопрос открытый.
Да и вообще. До поры человек с программатором или паяльником мог творить что угодно. И извечное простивостояние меча и щита никогда не закончится. Это ж один из ключевых двигателей прогресса.
Исходя из таких соображений крайне сложно отделить секретность (гарантированную неприкосновенность ключей в чипе) от безопасности (защиты программного продукта от недокументированного воздействия извне и адекватной реакции на него).
Вообще удивительно — но большинство тем уходит именно в эту область. А если уж до конца честно, то вопрос «security» я бы оставил исключительно для специальных применений. Сильно больше уделяя внимание именно «safety». Да, первое жизнь миллионов в руках политиков, но ведь второе жизнь каждого отдельно взятого индивидума. При чем практически всегда. Тут и боровые компьютеры в транспорте, и системы контроля утечек газа и много чего еще.
Во всех остальных случаях они толковые специалисты, вполне способные самостоятельно справляться с задачами любой сложности. Как и схемотехники — настоящие кудесники припоя и контактов. Как и остальные подразделения в моей организации. И это правильный командный дух. А в ночь перед сдачей мы все со спокойной совестью спим дома. К этому моменту вся работа уже сделана. Поэтому я, пожалуй, просто сделаю вид что ничего не заметил.
Спорить надо было раньше. Только это называется не спорить, а согласовывать. И это, конечно, обязательный этап. От него слишком многое зависит.
github.com/rust-embedded/cortex-m-quickstart — начало
github.com/rust-embedded/cortex-m — чуть более весело
rust-embedded.github.io/book — когда башню сорвет окончательно
В принципе с Cortex-M можно начинать работать. Конечно, это далеко не так хорошо как с С в части BSP (да даже CMSIS), но начинать можно. Боюсь только что кросскомпиляция далеко не самая приоритетная задача для авторов Rust.
В остальном со многим согласен. Хотя скажу честно — лично у меня вызывает некоторые сомнения Raspberry PI в конечном изделии. Мне спокойнее с хорошо зарекомендовавшими себя форматами от уважаемых и давно присутствующих на рынке производителей. Мое сердце рвется меду Phytec и Toradex. Но это мое. С Raspberry смущает ее доступность на длительных временных отрезках и относительная закрытость. Временами я с ней наблюдал загадочные явления, разгадать которые без Broadcom'а было практически невозможно. Ну и странная система старта (и безопасности обновлений как следствие) несколько охлаждает пыл.
, как и половое бессилие,приходит с годами. Я прекрасно помню времена развесных 1533/1554, казавшиеся невозможными технологии позволяющие провести аж два печатных проводника между их выводами и казавшийся высокочастотным сигнал в целых 4.096МГц.И трассировка DDR2/3/4 — далеко не самая страшная часть. Я больше скажу — грамотная трассировка питания, особенно в современных процессорных системах, пожалуй посложнее будет. Ну, или по крайней мере не проще. Просто DDR на слуху. Сегодня это своего рода пугалка про «черную-черную комнату». А граблей везде накидано — только успевай уворачиваться.
Про корпус на принтере. Да нет, не лишний шаг. Наоборот. Возможность быстро пощупать. А за одно хорошее подспорье технологу. Живой корпус и чертеж всегда лучше, чем просто чертеж. Так что абсолютно точно не лишний и бесполезный труд.
А вот по 737 MAX… Это действительно грустно. Уж казалось бы есть крайне немного сфер, где надежность и безопасность поставлена во главу угла. И авиация одна из них. И такой вот результат. Впрочем, наглядная демонстрация того самого философского вопроса про контроллеров контроллеров.
Впрочем, я не настолько пессимистичен как Вы. Мне кажется просто будет более жесткий водораздел между уровнями. Простейшая аналогия есть в области медицины. Там тоже времена универсальных специалистов прошли и наступила довольно жесткая специализация при обязательном владении базовыми принципами. Думаю, что IT рано или поздно постигнет та же участь. Оно уже есть. Я свою карму уронил до предела в спорах с прикладниками. Наивен был — думал удастся убедить. Ну да ладно, не о том сейчас. Сейчас о том, что прикладникам так или иначе нужны языки без «указателя на указатель по указателю», а системщикам не останется выбора кроме как использовать такую конструкцию. Конечно, системщиков нужно будет сильно меньше, чем прикладников. Но водораздел думаю будет, и будет довольно четкий. Это сейчас условный PHP-разработчик может довольно легко реализовать свой драйвер под тот же Linux. И даже довести его до mainline при должном желании. Думаю, в недалеком будущем нынешние программисты на C будут такими же странным товарищами, как сегодняшние Cobol'щики в финансовых сферах. Но спрос на них все равно останется.
И, конечно, у будущих системщиков не останется другого выбора кроме как осваивать безопасное написание своего кода. Хорошо, если к тому моменту появятся инструменты облегчающие данную задачу. Тот же Rust вполне годится как такой инструмент.
На меня в свое время произвела большое впечатление замечательная публикация Шенона «Надежные схемы из ненадежных реле». Я тогда впервые задумался над тем насколько реально писать надежный код на любой из современных архитектур. Ведь по сути чем ниже язык, тем больше он подвержен специфическим особенностям каждой конкретной архитектуры. И язык C, как один из самых низкоуровневых языков просто вынужден наследовать все косяки, которые только реализованы непосредственно в архитектуре вычислительной системы. А любой подъем выше порождает не менее известную проблему «кто контролирует контролеров». А если добавить сюда все возможные аппаратные сбои, на которые тоже надо адекватно реагировать, то все становится совсем грустно.
И по сути хотим мы того или нет, а у нас не остается выбора кроме как крутиться внутри этой ненадежной системы впадая в ту или другую крайность при этом постоянно исправляя те или иные косяки в тех или иных частях кода. Потому, думаю, даже в среднесрочной перспективе спрос на «безопасников» и «системщиков» никуда не денется. Как и спрос на прикладников.
Однако (чисто на вскидку) я бы поразмыслил на тему выделения критичных к производительности функций в отдельную секцию. И размещал эту секцию либо в RAM (минимизация задержек на считывание и выполнение инструкция) либо во FLASH если RAM мало. Linker script все равно у каждого проекта свой.
Ну, и про унификацию ниже правильно написано. Тут правда вопрос — что первично, а что вторично. Если первичен премиум, а бюджет — это для самых бедных и жадных, то есть смысл унифицироваться. Если наоборот — то надо думать.
Но еще раз — я Вашей кухни не знаю. Потому это просто иллюстрация к сказанному.
А теперь давайте вернемся к исходным предпосылкам. Смотрите — вы, как автор, знаете возможности Вашего изделия. И дальше Ваше с заказчиком совместное решение — или Вы делаете его целиком сами (что неизбежно увеличит сроки) или бьете задачу на части. Задираете себе схемотехнику, системную и драйверную часть и отдаете прикладную на откуп спецам заказчика. Это позволит сократить сроки получения готового изделия. Особенно если Вы сможете выдать прикладникам эмуляторы изделия (тот самый эмулятор LoRaWAN или трек с реального GPS). И, конечно, обговорите метрики производительности. В первом приближении аналогом современных ARM'ов вполне могут стать старые нетбуки c N270 атомом. Это и только это позволит избежать описываемых Вами проблем.
И еще раз — конечно, прототип с железкой близкой к реальной — это лучший вариант. Я нигде и никогда другого и не писал. Я писал только то, что далеко не всех такой вариант устроит. Хотя бы потому, что грамотно настроить систему кросс-сборки это тоже время, а собирать нативно на не блещущем производительностью ARM'е с ограниченной по размеру RAM — то еще удовольствие.