Проектирование встроенных систем подразумевает создание аппаратного обеспечения (печатной платы) и встроенного ПО. При этом проектировщик ограничен множеством факторов – доступными аппаратными ресурсами, требованиями к габаритам изделия, его стоимости и др. Все это порождает множество сложностей, с которыми приходится сталкиваться разработчику встроенных систем на каждом этапе работы. О них и пойдет речь.
Для ускорения проектирования аппаратное и программное обеспечение разрабатываются параллельно. Но чтобы никого не запутать, рассмотрим их и связанные с ними трудности отдельно.
Сложности разработки аппаратных средств
1. Сбор требований и составление ТЗ
Создание нового продукта начинается с возникновения и проработки идеи. Однако наша команда занимается контрактной разработкой электроники, поэтому с готовыми идеями к нам приходят заказчики. Соответственно, на первом этапе мы собираем требования к будущей системе:
Функциональные требования, которые описывают, что именно должно делать устройство;
Нефункциональные требования, которые описывают важные свойства и ограничения будущего устройства (габариты, производительность, надежность, условия работы, законодательные ограничения и т.п.).
И здесь мы сталкиваемся с первой типовой сложностью. Заказчикам сложно всесторонне описать будущее изделие и оценить реализуемость проекта. Поэтому самое важное на данном этапе – это помочь клиенту сформулировать требования к продукту. Для этого мы проводим подробно обсуждаем проект и спрашиваем, что должно делать устройство, сколько должно весить, какое будет питание, в каких условиях должно работать и т.д.
Некоторым заказчикам кажется, что мы задаем слишком много вопросов о мелочах. Но такой подход позволяет собрать максимально полные требования к продукту, не упустить важную информацию, а значит, избежать проблем на последующих этапах.
Классическая проблема заключается в том, что заказчики не сообщают команде какие-то детали, которые им кажутся очевидными, само собой разумеющимися.
Так, в одном из наших проектов после завершения первой версии устройства на базе микроконтроллера заказчик попросил добавить Ethernet-порт для удаленного управления устройством, но не уточнил специфику использования. Мы разработали вторую версию устройства, изготовили прототип, протестировали его и отправили заказчику. Получив прототип, тот пожаловался, что в аналоговом тракте устройства возникают посторонние шумы, чего не было в первой версии изделия. После долгого поиска источника помех выяснилось, что заказчик использует беспроводной удлинитель Ethernet, который влияет на работу нашего устройства. Поскольку заказчик предполагал такое использование устройства в качестве типового, то изделие пришлось дорабатывать, чтобы добавить дополнительную защиту от помех.
Кроме того, на этом этапе не стоит обещать заказчику больше, чем команде по силам выполнить. Если запрашиваемое клиентом решение нереализуемо, выгоднее честно в этом признаться, выделить решаемую задачей проблему и предложить какую-то альтернативу или компромисс, чем вызвать у заказчика завышенные ожидания.
2. Техническое предложение
Если ТЗ содержит в себе перечень требований к продукту, т.е. ставит задачи, то техническое предложение предлагает решения этих задач, т.е. описывает архитектуру создаваемой встроенной системы.
В рамках проектирования аппаратного обеспечения на этом этапе команда выбирает компоненты для будущей платы. Сложность здесь заключается в том, чтобы учесть различные ограничения:
А) Технические характеристики: объем памяти и производительность микроконтроллера, энергопотребление, тип питания, габариты, вес и т.д.
Б) Условия эксплуатации: влажность, экстремально высокие или низкие температуры, вибрация и т.п.
В) Стоимость и качество компонентов, которые определяют себестоимость конечного продукта.
Г) Доступность компонентов, которая определяет возможность производить продукт серийно (если перед заказчиком стоит такая задача).
3. Разработка схемы и проектирование печатной платы
Приступая непосредственно к проектированию платы, разработчики должны учесть массу тонкостей. Вот некоторые из них:
Опыт научил нас, что, имея дело с каким-то компонентом впервые, сперва стоит его протестировать, потому что реальные характеристики иногда отличаются от тех, что заявлены в документации.
Разработчики должны предусмотреть защиту от электростатических разрядов, электромагнитных помех, неблагоприятных условий среды и других факторов, если к устройству предъявляются соответствующие требования.
Если продукт предполагается выпускать серийно, необходимо придерживаться принципов DFM (учитывать требования производства).
Если продукт предполагается сертифицировать, плату нужно изначально проектировать с учетом соответствующих требований.
Необходимо придерживаться правил проектирования печатных плат, чтобы продукт получился надежным, долговечным и безопасным.
Много внимания уделяется отведению тепла. Должного охлаждения можно добиться за счет корректного размещения компонентов, добавления переходных отверстий, увеличения площади меди, установки радиаторов.
Когда нужно проверить работу того или иного компонента или если команда предлагает какое-то нестандартное решение и нет уверенности, что оно сработает как надо, команда сперва создает макет для проверки концепции. Такой прототип далек от финального продукта, имеет множество недостатков, но позволяет проверить работу компонентов, убедиться в реализуемости того или иного решения и выявить различные проблемы в самом начале разработки.
Иногда приходится создавать прототип не только платы, но и какого-то внешнего оборудования. Так, когда мы работали над алгоритмом компьютерного зрения для сельскохозяйственного робота, чтобы проверить работу встроенного ПО, мы заказали простенькую руку-манипулятор. Но одна его часть была слишком короткой, поэтому мы удлинили руку с помощью профильной трубы и созданных на 3D-принтере деталей для соединения.
4. Тестирование
Проектируемый продукт тестируется на каждом этапе работы. Это позволяет выявлять и устранять проблемы до того, как команда перейдет к завершающим испытаниям, которые проверяют, соответствует ли изделие техническому заданию и сертификационным требованиям, если таковые имеются.
Здесь нам часто приходится создавать специальную тестовую прошивку, а также прошивку для заводских испытаний.
Разработка встроенного программного обеспечения
1. Выбор аппаратных средств
В отличие от прикладного ПО, которое устанавливается на мощные ПК, смартфоны, планшеты или серверы, встроенное ПО ставится на оборудование, ограниченное по ресурсам. Это первая трудность, с которой сталкиваются разработчики.
Благодаря большому опыту наши специалисты могут оценить, сколько ресурсов нужно для будущего встроенного ПО, еще на этапе подготовки технического предложения. Конечно, проще всего разрабатывать прошивку под мощную микропроцессорную технику с большим объемом памяти, поскольку такое железо не потребует значительной оптимизации кода. Но это может быть существенно дороже в производстве, что негативно скажется на себестоимости конечного продукта.
Как упоминалось ранее, когда имеешь дело с незнакомыми аппаратными средствами, возникает другая проблема – документация на компоненты может отсутствовать или содержать ошибки и неточности.
Так, для одного из проектов команда выбрала модуль, который, согласно документации, мог получать координаты GPS и передавать данные по GSM. Но испытания показали, что делать это одновременно он не может.
Мы связались с разработчиком, и тот подтвердил, что модуль может одновременно работать только в одном режиме, а для переключения в другой режим модуль требуется переконфигурировать и перезагрузить. В документации об этом не было ни слова.
Как правило, получить нужную информацию можно, связавшись с разработчиком. Когда это невозможно, а альтернатив данному компоненту нет, команда изучает железо самостоятельно.
2. Архитектура встроенного ПО
Перед непосредственной разработкой встроенного ПО необходимо продумать архитектуру будущего решения. И здесь мы снова сталкиваемся с ограниченными аппаратными ресурсами, из-за чего команда не может использовать универсальный шаблон архитектуры для каждого проекта. Мы вынуждены выбирать наиболее оптимальный вариант из ограниченного числа шаблонов, который подойдет конкретному проекту.
Кроме того, если проект подразумевает создание ПО прикладного уровня, работу нужно начать со спецификации внешних интерфейсов встраиваемого ПО, чтобы другая команда могла приступить к своей части работы. Иногда мы также создаем mock-сервис, который эмулирует работу встроенного ПО и генерирует для высокоуровневого ПО синтетические данные. Такой подход ускоряет разработку и является обычной практикой в разработке встроенных решений.
3. Язык программирования и операционная система
Язык программирования выбирается исходя из того, какой тип ПО нужно разработать и какие аппаратные средства нам доступны. Так, встроенное ПО для устройств на базе Android пишется на Java, а ПО для одноплатных компьютеров – преимущественно на C или C++.
Хотя функционал устройства нередко можно реализовать без использования операционной системы, наличие ОС упрощает и ускоряет разработку, а также повышает портируемость разрабатываемых приложений.
Здесь выбор довольно широк (Embedded Linux, Android, Windows IoT, RTOS, RTEMS и др.) и зависит от таких факторов, как:
Цели проекта;
Производительность железа;
Стоимость разработки.
Впрочем, бывает и так, что какую-то функцию проще реализовать без какой-либо ОС. Например, если перед разработчиком стоит задача выдерживать тайминг в 1 мкс, реализация этой функции под управлением ОС Ubuntu займет много времени. Потребуется написать специальный драйвер, который будет работать в режиме реального времени на уровне ядра. Реализовать этот функционал гораздо проще и быстрее непосредственно на микроконтроллере. К тому же, под управлением ОС код работает несколько медленнее, а сама ОС требует дополнительных ресурсов.
Часто чем больше аппаратных ресурсов доступно разработчику, тем дешевле сама разработка, и наоборот.
В случаях же, когда использование ОС оправдано (например, когда нам нужен красивый интерфейс пользователя), дешевле и проще работать со свободно распространяемыми ОС, чем с коммерческими платформами.
4. Частые трудности при реализации встроенного ПО
В устройстве может быть очень много функций и очень сложная логика с обработкой сигналов, различными алгоритмами и т.п. При этом разработчик ограничен в аппаратных ресурсах.
К числу наиболее частых сложностей, с которыми сталкивается команда, можно отнести следующие.
Недостаток информации
Встроенные программы всегда разрабатываются под специализированное аппаратное обеспечение, поэтому много времени тратится на его изучение.
Так, в одном из проектов мы должны были создать решение, которое отправляло бы команды в виде последовательностей байтов в шестнадцатеричном представлении на компьютеры MacBook через USB-порт. Сама по себе задача простая, но в официальных документах Apple нигде не раскрывается, как кодируются те или иные команды. Нужную информацию пришлось искать самостоятельно.
Шифрование данных
Если устройство передает данные по сети, а сами данные содержат конфиденциальную информацию, то их необходимо шифровать. Например, устройство, над которым мы сейчас работаем, передает биометрические данные через Интернет, и заказчик потребовал обезопасить соединение.
Однако шифрование данных требует дополнительных ресурсов, а значит, повышает требования к железу.
Ограниченность памяти и производительности
Пару десятилетий назад проблема нехватки памяти во встроенных системах стояла особенно остро. Сейчас характеристики железа значительно выросли. С другой стороны, требования к производительности встроенных устройств тоже продолжают расти, а сами устройства становятся все меньше. Так что проблема сохраняется.
Если устройство питается от батареи, мы также сталкиваемся с ограничениями по энергопотреблению. Для минимизации энергопотребления может потребоваться оптимизация кода, отключение неиспользуемых модулей/периферии в устройстве, а также перевод устройства в спящий режим, когда его работа не востребована.
Новые требования
Бывает так, что уже на этапе написания кода заказчик выдвигает новые требования к функционалу устройства или ПО. Может оказаться, что ресурсов выбранных аппаратных средств не хватает и проект приходится значительно перерабатывать.
Оптимизация
Встроенное ПО можно сделать быстрым, но требовательным к объему памяти или нетребовательным к объему памяти, но медленным. И здесь важно найти баланс. Помогают в этом современные компиляторы, в арсенале которых множество типов оптимизации.
5. Тестирование и отладка
В половине случаев протестировать встроенное ПО, не отходя от компьютера, нельзя. Нужны тестовые стенды, а часто и полевые испытания. И здесь тестировщикам приходится проявлять изобретательность.
Так, в рамках одного проекта мы разработали устройство с модулем, измеряющим дистанцию до препятствий. С помощью 3D-принтера мы создали стойку, к которой крепилось изделие, а сама стойка фиксировалась на капоте машины с помощью магнита. Затем разработчики отправились на парковку и долго катались среди автомобилей, следя за работой устройства.
Бывает так, что команде приходится разрабатывать встроенное ПО для устройства, которого у нас нет. Тогда тестировать решение приходится удаленно.
Обычном мы используем TeamViewer. Программа устанавливается на удаленном компьютере. К нему также подключаются камера и тестируемое устройство. Подключившись к ПК, разработчик дает команды устройству и наблюдает за его реакцией по камере.
Еще одна сложность связана с тем, что при тестировании встроенного устройства сложно определить, что именно вызывает ошибку – железо или ПО. Определить это особенно трудно во время полевых испытаний, когда у команды ограниченный набор диагностических инструментов.
В рамках одного из проектов мы тестировали устройство, состоящее из одноплатника и двух печатных плат. Компьютер должен был передавать на одну из плат пакет Heartbeat. Так плата понимает, что одноплатник все еще работает. Если плата не получала пакет, она должна была перезагружать компьютер. На испытаниях перезагрузки следовали одна за другой, чего не должно было происходить. Мы проверили шину логическим анализатором. Он показал, что компьютер отправлял корректный сигнал. Следовательно, причину неисправности следовало искать в прошивке платы. Впоследствии так и оказалось: ПО некорректно обрабатывало пакет.
Здесь я перечислил трудности проектирования встроенных системы, которые мне показались наиболее типовыми. На практике же я и моя команда сталкиваемся с самыми разными сложностями, и перечислить все вряд ли возможно.