Embedded software engineering 101: введение
Я запускаю цикл статей по обучению разработке встроенного программного обеспечения. Мы начнем с описания простого микроконтроллера, и после того, как Вы поймете, как он работает, разовьем это до понимания работы относительно сложных систем, таких как Fitbit или Nest.
Я назвал эту серию Embedded Software Engineering 101, и она начинается с этой недели прямо здесь в этом блоге.
Продолжайте читать для дальнейших объяснений и подробностей.
Одни строительные блоки на других строительных блоках.
Я работаю со встроенными системами и разрабатываю микросхемы уже более 14 лет. Мне нравятся встроенные системы — железо, софт и ограничения, которые связывают их вместе.
Любительская электроника и такие идеи, как Arduino, Adafruit и Sparkfun дали возможность легко накидать что-то из железа и софта за выходные (или месяц, или семестр), создав что новое, интересное и может быть даже полезное.
Это здорово! Предоставление людям возможности созидать — изумительная штука; если бы я хотел выражаться выспренно, то с придыханием назвал бы это «демократизирующей технологией».
Большая часть любительских проектов единовременные. Вы собираете нечто, делаете это настолько хорошим, насколько хватает времени или энергии, и двигаетесь дальше.
Я провел свою карьеру на противоположном конце спектра — создавая продукцию, которая выпускается в сотнях тысяч или миллионах или больше экземпляров — и это требует совсем другого образа мышления и системного подхода.
Я хочу учить людей, как писать встроенное ПО для такого рода систем. Я уже давно вынашивал эту идею курса/руководства/книги/блога «Embedded Software Engineering 101», и благодаря блогу Embedded.fm начинаю ее реализацию сейчас.
Я человек фундаментального типа, так что мой план — начать с основ, с простого описания простого микропроцессора, и развивать эту основу, пока вы не поймете, как работает относительно сложная встроенная система.
Моя цель — чтобы к концу этого цикла вы могли разобраться как работает Fitbit, термостат Nest или подобная встроенная система. Вы сможете начать работать со встроенными программными системами используя профессиональный опыт.
Embedded Software Engineering 101 предназначен для:
- Выпускников вузов в сфере компьютерных наук, компьютерной инженерии или электроники, интересующихся встроенными системами.
- Электронщиков-любителей, желающих более глубоко понять, как работает их система на Arduino, и узнать, как им двигаться дальше (и нужно ли!).
- Профессиональных программистов без опыта со встроенными системами, желающих сместиться вниз по технологическому стеку и понимать, как они работают.
- Инженеров, работающих со встроенными системами и желающих понять, чем занимаются их коллеги-программисты.
Так вот, я не Фейнман, но я уверен, что лучший способ понять систему — это начать с основ. Вооруженные этим пониманием, вы сможете создавать простые встроенные системы с простым софтом. И поняв сначала очень простую программу, вы сможете развивать это, создавая более сложное ПО по мере роста опыта.
Основы в первую очередь — это конечно только мое личное убеждение. Множество людей сделали полезные штуки с Ардуино без понимания чего бы то ни было из основ. Этот цикл статей для тех, кто все-таки хочет понимать основы и все, что на них построено.
Конечно мы должны задаться вопросом — где правильный уровень чтобы начать с этих самых «основ»? Транзисторы и логические вентили? Нет, это слишком низкий уровень для старта со встроенным ПО. Подключение к распространенным датчикам? Нет, это слишком высокий уровень, требуется слишком много знаний чтобы начать с этого.
Я думаю правильный уровень основ это встроенный микропроцессор. Не обязательно понимать физику или электронику чтобы использовать встроенный микропроцессор, также не обязательно быть экспертом в программировании.
Так что с этого мы и начнем в следующей статье.
Предупреждение о предвзятости: в прошлой жизни я был архитектором/разработчиком процессоров. Начать этот цикл с понимания как работает ЦПУ может быть не лучшим способом для понимания встроенных систем, но именно так работает мой мозг. Обязательно попробуйте другие курсы/руководства и т.д., если не станете понимать этот после нескольких статей.
Embedded software engineering 101: основы микроконтроллера
Мы начнем наше путешествие Embedded Software Egineering 101 со скромного микроконтроллера. Микроконтроллер (или микропроцессор) это основной строительный блок всех вычислительных систем, встроенных и прочих.
МК кажется довольно сложным, но он состоит из трех простых вещей: инструкции, регистры и память. Инструкции это те штуки, которые микроконтроллер знает как выполнять. Простой МК умеет выполнять не так уж много — у него может быть например 20 или 30 инструкций. В дальнейшем в этом цикле я буду использовать микроконтроллер MSP430 от Texas Instruments, у которого только 27 инструкций.
Просто фотография МК (TI MSP430F5529)
Эти 27 инструкций — единственное, что MSP430 умеет делать. Он может сложить два числа, вычесть из одного числа другое, переместить числа с одного места в другое или выполнить 24 другие простые операции. 27 операций может показаться недостаточно чтобы сделать что-либо полезное, но на самом деле их хватит с избытком, чтобы выполнить любую мыслимую программу.
Хорошо, значит у микроконтроллера есть инструкции, которые делают что-то с числами. Но где находятся эти числа? Регистры и память! Инструкции оперируют числами, которые хранятся в регистрах и памяти.
Регистры это очень быстрое хранилище, содержащее числа, которыми оперируют инструкции. Можно думать о них, как об используемом инструкциями блокноте. МК содержит немного регистров, обычно 8-32. Например, у MSP430 16 регистров.
Память это тоже хранилище для чисел, но она гораздо объемнее и медленнее чем регистры. У микроконтроллера может быть 64 кБ, 256 кБ или даже более 1 МБ памяти. У MSP430F5529 около 128 кБ памяти; это более чем в 8000 раз превосходит количество его регистров!
Прежде чем мы начнем рассматривать примеры, я призываю вас достать лист бумаги и ручку или карандаш и прорабатывать эти примеры по мере чтения. Прорабатывать их на бумаге сложнее, чем просто читать, что я написал. Таким образом вы внимательнее подойдете к процессу, и шансы на запоминание изученного будут выше.
Давайте рассмотрим вымышленный, но характерный пример микроконтроллера.
Пусть скажем у нашего МК 4 регистра и 8 ячеек памяти. Регистры обычно называют как-нибудь креативно, например «R0», «R1» и т.д., поступим и мы так же. На ячейки памяти обычно ссылаются по их номерам, также называемым адресами памяти, начиная нумерацию с 0. Вот так будут выглядеть наши регистры и память:

И теперь я помещу в них некоторые значения:

Теперь нашему вымышленному микроконтроллеру нужны какие-нибудь инструкции.
Совокупность инструкций, которые знает МК, называется его набором инструкций. Пусть скажем в наборе будет три инструкции: ADD (сложить), SUB (сокращение от «subtract» — вычесть) и MOVE (переместить). Инструкции должны получать откуда-то числа, которыми они оперируют, и также помещать куда-то свои результаты, так что некоторые из них содержат информацию о том, где находятся входные и выходные данные.
Пусть, например, у нашей инструкции ADD два источника и один приемник данных, и все они должны быть регистрами. Руководство может описывать эту инструкцию примерно так:
Это общепринято в инструкциях — использовать один из источников также в роли приемника, как делает инструкция ADD, используя регПрм в качестве и источника и приемника данных.
«ADD R1, R2» — это язык ассемблер для микроконтроллера, это нативный язык программирования МК.
Давайте определим SUB в том же стиле:
И наконец пусть у инструкции MOVE один источник и один приемник, и либо:
- оба аргумента регистры, либо
- один — регистр и один — ячейка памяти.
Одно замечание о слове «move», используемом для этой инструкции: большая часть наборов инструкций используют именно его, хотя в действительности данные копируются, а не перемещаются.
Название «move» может создать впечатление, что операнд-источник инструкции уничтожается или очищается, но на самом деле он остается в покое, модифицируется только приемник.
Давайте пройдемся по нескольким примерам используя наш вымышленный микроконтроллер.
На старте наши регистры и память выглядят так:

Теперь выполним на МК следующую инструкцию:
Она берет значение R1, складывает его со значением R2 и сохраняет результат в R2. Процессор выполняет большую часть инструкций за одну операцию, но я разобью выполнение каждой инструкции ADD, SUB и MOVE на несколько шагов стрелкой «=>» ведущей через замены (регистр/память => значение):
После выполнения этой инструкции память неизменна, но регистры теперь выглядят следующим образом, с изменившимся значением написанным красным:

Обратите внимание, что R1 неизменен; изменился только регистр-приемник R2.
Следующей давайте попробуем инструкцию SUB:
Она берет значение R3, вычитает его из значения R0, и сохраняет результат в R0:
После выполнения этой инструкции память неизменна, но регистры теперь выглядят таким образом:

И наконец давайте попробуем пару версий инструкции MOVE:
Эта инструкция MOVE копирует в R0 значение R2:
И теперь регистры выглядят так:

Дальше мы скопируем регистр в память:
Эта инструкция MOVE копирует в ячейку памяти 3 значение R3. Квадратными скобками в нашем наборе инструкций обозначаются ячейки памяти.
Регистры неизменны, но память меняется:

И для нашего последнего примера мы скопируем значение из памяти в регистр:
Здесь значение ячейки памяти 6 копируется в регистр R0:
Память неизменна, а регистры теперь выглядят следующим образом:

Верите или нет, но если вы поняли большую часть того, что мы только что обсудили насчёт инструкций, регистров и памяти, то вы понимаете основы микроконтроллеров и языка ассемблер.
Конечно я опустил множество деталей. Например, как МК получает инструкции для выполнения?
Есть ли более интересные инструкции, чем только простые математические и инструкции копирования? Память это то же самое, что RAM или флэш, или нет?
Embedded systems: что это? Коротко про встраиваемые системы
![]()
Embedded System — это системы, которые выстраиваются на уровне микропроцессоров и микроконтроллеров. Они отвечают за какие-то специальные функции приложения или устройства и являются частью более крупных систем приложения, а не самостоятельной частью.
Пример применения таких систем можно увидеть в любом современном мультимедийном оборудовании. Embedded System — это возможность выбирать музыку, которую хотите слушать , или фотографию , которую хотите просмотреть. Все это становится доступным благодаря применению микропроцессор ов , которые управляют данными функциями. А работа этих микропроцессоров — это и есть наши рассматриваемые системы.
Embedded System — это не весь гаджет или персональный компьютер. Это лишь небольшая его часть, которая отвечает строгим требованиям к системе. Каждая такая система может выполнить лишь ограниченное количество операций, на которые она запрограммирована. Исходя из своего назначения, Embedded System может означать всего лишь «прошивку» для какого-то устройства или целую операционную систему с набором программного обеспечения , опять же , для какого-то другого устройства.
Где используются Embedded System?
-
измеряющем оборудовании: осциллограф, анализаторы и т. д . ;
-
бортовом компьютере автомобиля;
-
телекоммуникациях;
-
медицинском оборудовании;
-
производственных станках;
-
разнообразных роботах;
-
бытовой технике;
-
разнообразных гаджетах;
-
банкоматах;
-
кондиционерах;
-
навигационных системах;
-
системах безопасности и сигнализации;
-
и др.
Как работают Embedded System?
-
ASIC — интегральные схемы;
-
FPGA — программируемые логические матрицы;
-
прочие компоненты, предназначенные для наладки взаимодействия с интерфейсом пользователя.
Как программируют Embedded System?
Программирование Embedded System не ограничивается только знаниями самого языка программирования, также нужно понимание электроники, информатики, автоматизации процессов, робототехники и друго го — многое зависит от области применения встраиваемых систем. Поэтому можно сказать, что Embedded-программист — это не просто программист, а специалист широкой направленности.
Разработка Embedded System будет состоять из продумывания аппаратной части системы и проработк и программных скриптов. Программные скрипты бывают разной сложности — это зависит от приложения , для которого они разрабатываются. Многие прогрессивные сферы, такие как медицина, авиация, вооружение, космос, роботы и др. , имеют собственные библиотеки и инструменты для разработки своих встраиваемых систем. Поэтому Embedded-программист в этих сферах — это очень узконаправленный специалист, который владеет инструментами только для конкретной сферы деятельности.
Чтобы встраиваемая система получилась максимально успешной, к ее разработке нужно подходить очень ответственно и обязательно хорошо продумать архитектуру и функциональность. Очень часто небольшие ошибки приводят к тотальному провалу систем, поэтому программирование должно быть аккуратным, а тестирование — очень тщательным.
Иногда Embedded System бывают настолько сложными, что их разработка превращается в целое событие, которое управляется несколькими командами инженеров и программистов.
Заключение
-
искусственного интеллекта;
-
технологий дополненной и виртуальной реальности;
-
машинного обучения;
-
робототехники.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Кто такой Embedded-разработчик. Обзор изнутри от Вадима Егораева
О профессии рассказывает Вадим Егораев, Software Engineering Team Leader в ЕРАМ, 10 лет в ИТ, развивает программы тренингов для Embedded-разработчиков.
Продолжаем цикл материалов про ИТ-специальности. Каждую из них описывает «типичный представитель» — опытный специалист. Надеемся, что цикл поможет школьникам, студентам, переквалификантам, джуниорам и сочувствующим выбрать специальность в ИТ, оценить свои перспективы или просто сверить часы с авторитетным коллегой. Можно обсуждать и дополнять материал в комментариях, чтобы сделать его ещё полезней. Спикер и автор материала поддержат дискуссию и ответят на вопросы.
О профессии рассказывает Вадим Егораев, Software Engineering Team Leader в ЕРАМ, 10 лет в ИТ, развивает программы тренингов для Embedded-разработчиков.
Продолжаем цикл материалов про ИТ-специальности. Каждую из них описывает «типичный представитель» — опытный специалист. Надеемся, что цикл поможет школьникам, студентам, переквалификантам, джуниорам и сочувствующим выбрать специальность в ИТ, оценить свои перспективы или просто сверить часы с авторитетным коллегой. Можно обсуждать и дополнять материал в комментариях, чтобы сделать его ещё полезней. Спикер и автор материала поддержат дискуссию и ответят на вопросы.
Что такое Embedded-разработка?
Это разработка встроенного программного обеспечения. Я определяю Embedded-разработку как «практически всё, что делается не под компьютер, мобильный телефон и сервер».
Встроенное ПО есть во многих привычных вещах. Например, беспроводные наушники — передача данных на них идёт при помощи софта. Веб-камеры — в звуковой карте есть ПО, которое управляет громкостью, входами, выходами, переключает их. Ещё люди ездят на машинах, смотрят телевизор, фотографируют на камеру и т. д. — процессоры сейчас есть практически везде, и Embedded-разработчики пишут для них ПО.
Как развивалась отрасль?
Активное развитие устройств со встраиваемыми системами началось, когда процессоры стали низкопотребляющими, достаточно дешёвыми в выпуске и внедрении. Личный пример: если в 1988 году у моего Audi 100 не было внутри никакой цифровой электроники, то в середине 90-х появились первые устройства, которые управляли системой антиблокировки тормозов (ABS) на основе процессора. А с 2000-х цифровой электроникой стали контролироваться стёкла, дворники, фары и всё, что угодно.
Последние 5 лет в тренде — умные устройства вроде интеллектуального чайника, роботов-пылесосов, смарт-ламп и область IoT в целом. Развитие направления происходит, в том числе, благодаря таким платформам, как AWS, Azure, Microsoft и GCP, к которым можно быстро и качественно подключать сотни тысяч умных устройств, а затем обрабатывать данные с них.
Чем занимается Embedded-разработчик?
Рассказать легче в сравнении. У разработчика, который пишет на Java, Python или других высокоуровневых языках, 70–80% времени уходит, чтобы создать само ПО. То есть бизнес-логику — разработку того, что приходит из требований заказчика.
У Embedded-инженеров наоборот: они используют 70% времени, чтобы заставить платформу работать. Мы создаем все условия, чтобы ПО запустилось, можно было принимать данные от сенсоров, управлять мотором, работать с драйверами и загрузчиками, светить светодиодами и так далее в зависимости от контекста. Делаем то, что не связано с непосредственными задачами устройства.
Типичные задачи Embedded-разработчиков: написать что-то, что даёт данные или куда-то их пересылает. Например, принять данные от температурного датчика и передать их в облако. Другой задачей может быть написание, скажем, драйвера сенсора.
Какие знания пригодятся?
- Понимать платформенные особенности: как устроены процессоры и микропроцессорные системы, каким образом данные располагаются в памяти, про кэш данных, как работает программа, как происходит ее исполнение с операционной системой и без и др.
- Знать базу: что такое системы версионирования, bug-трекеры и СI-инструменты, такие как Jenkins или Azure DevOps.
- Из языков программирования чаще всего нужен С, хотя в последнее время всё больше Embedded-программ пишутся на С++. Процессоры становятся дешевле в производстве, поэтому почти в каждое устройство можно поставить Linux — серьёзную систему, которая фактически даёт возможность писать встроенное ПО на любом языке программирования.
- Электроника — один из главных пунктов. Все встроенные устройства сделаны на базе специализированных приборов, которые предназначены для решения конкретных задач. Они очень разнообразны и отличаются друг от друга схемотехникой, набором периферии, элементной базой. Embedded-разработчик должен уметь разбираться во всём этом: читать схему устройств, понимать, как это воплощено в печатных платах, как работают сенсоры и так далее.
- Понимать специфику работы операционных систем разного рода и как отлаживать код в ОС реального времени. Во встроенном ПО обычно есть одна конкретная цель, например, включить-выключить реле, которую важно сделать вовремя (счёт идет на мили- или микросекунды). Linux и Windows, например, этого гарантировать не могут, потому что их главная задача — равномерно и честно распределить процессор между всеми программами. А вот ОС реального времени гарантирует, что посылаемый сигнал точно дойдет вовремя. Порой это очень критично: задержка исполнения сигнала в тормозной системе машины может привести к большому ущербу здоровью и жизни человека.
- Знать прикладные области, где встроенное ПО используется. Например, поскольку IoT становится всё более популярным, Embedded-разработчику стоит знать всё, чтобы подключить устройство к облакам. Это и беспроводные технологии, такие как Bluetooth и Wi-Fi (основные), LoRa и Narrow-Band IoT — список большой. Кроме того, нужна «база» о сетях: как работает интернет, что такое роутеры, DNS, DHCP и высокоуровневые интерфейсы, к которым мы все привыкли, например, HTTP. Еще есть специфические, узконаправленные знания, например, в автомобильной, медицинской и промышленной отраслях. Они приобретаются с опытом, во время работы на проектах.
- Безопасность. Часто клиенты не хотят подключать свои устройства в интернет, потому что боятся взломов. Поэтому сейчас большое внимание уделяется соединению по безопасным каналам, а все прошивки, которые на них заливаются, подписываются специальными сертификатами, чтобы их невозможно было подменить. Поэтому Embedded-разработчику нужно знание криптографии: ассиметричной и симметричной, как работают аутентификация, подписи и блочное шифрование, как вообще хранить ключи шифрования на устройстве, чтобы их невозможно было украсть или подменить.
Завершу список упорством и постоянным саморазвитием. Элементная база непрерывно обновляется, как и наборы инструментов, и среды разработки — нужно изучать, что происходит в отрасли и около неё, чтобы быть «на гребне волны».
В каких направлениях можно работать?
Самые разные сферы, диапазон проектов большой. В ЕРАМ я занимался и рулевым управлением автомобиля, и кофеваркой, и зарядкой для электромобилей, которую используют в частных домах, и преобразователями интерфейсов, и сетевым ускорителем DNS запросов и многим другим. Всё зависит от специфики компании, в которой вы работаете, и доменов заказчиков. В любом случае, Embedded-разработка всегда очень интересная и разноплановая, особенно в больших компаниях, куда приходят разные клиенты.
Возможность смены профессии
Вариантов много. У нас даже шутка есть: главное требование для разработчиков встроенного ПО — не убежать в Java. Потому, что на Java сегодня пишутся много интересных проектов для самых разных областей. Например, в нашем департаменте Embedded, Standalone & IoT Delivery есть и Java, и Python, и Ruby, и Go, и еще много разных стеков. Что привлекает и держит меня в своей области? Возможность видеть вживую и трогать руками то, что делаешь (плату, например), а потом сразу наблюдать за результатом работы. Твой продукт не просто где-то там на сервере крутится на другой стороне планеты, а лежит у тебя на столе, светится, издает звуки и т. д.
Где учиться?
Если с нуля, то лучший вариант базы — электроника (сам так начинал). Ребята, которые закончили кафедры БГУИР, БНТУ и региональных технических университетов по специальностям промышленной электроники, автоматизации или общей электроники, имеют подходящий набор скиллов и знаний (например, понимание цифровых схем и азов программирования), чтобы стать хорошим Embedded-разработчиком. Потом им остается прокачаться в области ПО. Кстати говоря, мы так и делаем: доучиваем студентов-электронщиков, чтобы потом взять их в команду.
Переквалификация. В Embedded проще прийти из C и С++. Это лучший вариант: так как нам довольно часто приходится работать с памятью, то очень важными оказываются знания в логике работы указателей, которые есть далеко не во всех языках программирования.
Для самостоятельного обучения из онлайн-курсов могу посоветовать Coursera и LinkedIn Learning. Там есть и про Linux, и про операционные системы, и про разработку встроенного ПО, и про криптографию:
П. С. Про работу и хобби
Помимо разработки я увлекаюсь музыкой, сейчас активно учусь игре на электрогитаре. Моя работа и хобби пересекаются и дополняют друг друга, ведь электронная музыка и встроенное ПО сильно связаны. Вообще я и начинал изучать электронику со звуковой и звуковоспроизводящей электроники. Знаю, как работают микрофоны, динамики, звуковые карты, цифровые сигнальные процессоры, как создаются звуковые эффекты — это помогает мне развиваться как музыканту, видеть мир звуковоспроизведения и звукозаписи с нескольких сторон. Например, я понимаю, какие звуковые волны происходят из моего музыкального инструмента, как они распространяются, почему что-то идет не так или не работает. А различные звуковые эффекты мне представляются цифровыми фильтрами определенного рода.
Среди моих знакомых Embedded и IoT-инженеров есть много ребят с очень интересными и необычными хобби, они постоянно пробуют что-то новое. Пожалуй, это отлично поддерживает креативность и вдохновляет мыслить outside the box — советую!