Отличия разработки встроенного ПО от разработки обычных программ
Прототипирование включает в себя не только проектирование и сборку платы, но также и разработку встроенного программного обеспечения, которое обеспечивает функционирование аппаратных компонентов. Встроенное программное обеспечение обычно состоит из драйверов устройств, операционной системы и системного программного обеспечения. Драйверы устройств напрямую взаимодействуют с периферией и управляют ею. Системное ПО обеспечивает исполнение общей логики работы устройства.
Разработка встроенного программного обеспечения отличается от создания прикладного программного обеспечения. Большинство прикладных приложений манипулируют данными - они хранят их, перемещают, отображают и выполняют вычисления на их основе. Приложения абстрагируются от оборудования, на котором они исполняются. Основной задачей разработчика приложения является реализация логики, обеспечивающей функциональность приложения.
Встроенное программное обеспечение отличается тем, что каждая строка встроенного кода напрямую влияет на оборудование. Оно манипулирует аппаратным обеспечением на физическом уровне, обеспечивая заложенную разработчиком логику работы устройства. Разработчики встраиваемого программного обеспечения должны понимать особенности используемых компонентов и их связи друг с другом, что требует умения читать схему, понимания даташитов и другой документации на электронные компоненты, а также навыков использования контрольно - измерительного оборудования.
Поскольку область использования встраиваемых систем расширяется, а вычислительные возможности используемых в них процессоров становятся все более значительными, в разработке встраиваемых систем возрастает роль классических программистов. Однако и потребность в разработчиках встроенного программного обеспечения, которые используют код для непосредственной манипуляции аппаратным обеспечением устройства, остается по прежнему высокой.
Типичный процесс разработки встроенного программного обеспечения
При разработке встраиваемых систем инженеры-электронщики тесно сотрудничают с разработчиками встраиваемого программного обеспечения для выработки общих решений, уточнения используемых компонентов, схемы и принципов работы устройства, хотя их роли различны.
Типичный процесс разработки встроенного программного обеспечения выглядит следующим образом:
Совместное проектирование
Инженеры-электронщики начинают выбирать компоненты, необходимые для создания системы. Именно в этот момент к ним подключается разработчик встроенного программного обеспечения, чтобы убедиться, что они выбирают правильный микроконтроллер или цифровой сигнальный процессор для того, чтобы обеспечить необходимый функционал приложения.
Дизайн-ревью
После разработки принципиальной схемы разработчики встроенного ПО совместно с разработчиками схемы обсуждают результат их труда, чтобы убедиться, что все сигналы и соединения понятны. Иногда это требует переработки части схемы, так как выводы могут работать не так, как планировалось изначально.
Аппаратная эмуляция
Затем разработчик создает тестовый модуль или аппаратный эмулятор, который будет имитировать сигналы, присутствующие в разрабатываемом проекте. Это позволяет быстро выполнять итерацию и разработку отдельных компонентов кода. На этом этапе уже можно увидеть уровни и форму сигналов и создать минимальный функционал встраиваемого ПО. Эмуляция особенно важна в силовых приложениях, где ошибки в коде могут привести к перегоранию компонентов.
Тестирование платы
После того, как появляется собранная плата, разработчики встраиваемых систем начинают тестировать ее основные функции, чтобы проверить, можно ли ее включить, правильно ли плата взаимодействует с периферийными устройствами, установлены ли правильные напряжения в преобразователях и т. д.
Сборка драйверов
Хорошие драйверы - основа любого устройства. Лучше потратить больше времени на написание хороших драйверов, чем потом тратить время на модификацию кода при добавлении нового периферийного устройства или аксессуара. Например, вы разрабатываете драйвер интеллектуального зарядного устройства. И вам нужно добавить новый аксессуар, который необходимо зарядить. Хороший драйвер потребует только описания того, как происходит процесс зарядки. Все остальное, что связано с конкретными выходами и элементами управления, будет уже описано внутри драйвера.
Реализация логики
Разработчик встроенного программного обеспечения реализует в коде логику, которая заставляет устройство делать то, для чего оно задумывалось. Основой для программирования служат спецификации, подготовленные разработчиками электроники и техническое задание на разработку продукта. Это последний этап разработки встроенного программного обеспечения. На этом этапе устройство должно заработать, и вам останется только совершенствовать код.
Разумеется, разработка может включать несколько итераций прототипов. И для каждой итерации потребуется доработать код.
Операционные системы и языки программирования
Для многих встроенных решений требуется операционная система (ОС), которая работает в качестве посредника между драйверами оборудования и логикой приложения. Большинство ОС, используемых в микроконтроллерах, представляют собой операционные системы реального времени (RTOS), что означает, что они должны обрабатывать задачи за время, меньшее чем интервал между задачами. Это важная особенность устройств, которые управляют вещами реального мира в режиме реального времени.
Встраиваемые операционные системы
RTOS бывают разных размеров и возможностей. Некоторые из них проприетарные, а другие с открытым исходным кодом. Некоторые производители микроконтроллеров разрабатывают RTOS для своих продуктов, в то время как другие просто дают список совместимых ОС. Выбор операционной системы зависит частично от микроконтроллера (младшие семейства контроллеров имеют меньше памяти для программного обеспечения) и, частично, от сложности реализуемых задач. При выборе контроллера необходимо учитывать, сколько памяти потребуется для запуска драйверов, ядра системы и логики приложения. Многие разработчики встраиваемых систем предпочитают RTOS с открытым исходным кодом, поскольку она обеспечивают большую гибкость при обновлении системы.
В течение многих лет традиционным языком разработки встроенного программного обеспечения был Ассемблер, который легко компилируется в машинный язык. Сегодня большинство разработчиков встроенного программного обеспечения используют семейство языков C, потому что они более интуитивны и проще в обслуживании.
И C, и Ассемблер позволяют непосредственно общаться с регистрами микроконтроллера и управлять периферийным оборудованием. Многие производители микроконтроллеров предоставляют свои собственные версии C и готовые библиотеки с оптимизированным кодом, облегчающие использование контроллера. Иногда для разработки встраиваемых решений используется язык C++, но это не всегда правильный выбор. Хотя этот язык обладает всеми преимуществами объектно-ориентированного языка программирования, реализованный с его помощью код часто занимает больше места и может работать медленнее. Разумеется, для некоторых встроенных решений, которые менее критичны к ресурсам, C++ может стать хорошим выбором. Также можно использовать C++, если у вас есть возможность заложить в проект контроллер с более высокой тактовой частотой и большим объемом памяти.
Интегрированная среда разработки (IDE)
Для большинства микроконтроллеров есть рекомендованные производителем IDE, кроме того, на рынке представлено множество сред разработки, подходящих для различных контроллеров. Например, Eclipse - широко используемая IDE с открытым исходным кодом, которая поддерживает широкий набор контроллеров. Некоторые производители выпускают свои расширения для Eclipse. В принципе, разработку можно вести в любой удобной вам среде, независимо от того, создана она производителем или сторонним разработчиком. В некоторых случаях, придется потратить часть времени на конфигурирование IDE и выбор драйверов.
Основные инструменты разработки встраиваемых систем
Один из важнейших инструментов для разработки встроенного программного обеспечения - это отладчик, который позволяет вам пошагово выполнять код и исследовать состояние контроллера и других компонентов на плате. Когда вы отлаживаете код, очень важно иметь возможность остановить программу, выполнить отдельную функцию и проверить, что все находится в том состоянии, как вы ожидаете, узнать значения переменных, регистров и т. д.
Использование осциллографа при разработке источника питания
Чтобы выполнить отладку, вам потребуется внутрисхемный эмулятор или JTAG- отладчик.(JTAG - это стандартный интерфейс, используемый для программирования, тестирования и отладки во многих микроконтроллерах). Кроме того, обязательно потребуется мультиметр, часто нужен осциллограф и другое контрольно-измерительное оборудование.
Синхронизация итераций разработки прототипов и встроенного ПО
Обычно разработка прототипов носит итерационный характер. В этом случае синхронизация разработки аппаратного и встраиваемого программного обеспечения может быть сложной задачей. Для успешной реализации проекта очень важно, чтобы программисты и разработчики платы работали в тесном контакте друг с другом.
Между разработчиками встраиваемых систем и программистами, создающими обычные приложения, есть еще одно фундаментальное отличие. Разработчики встроенного программного обеспечения ограничены аппаратным обеспечением. Их реальность такова, что сначала выбирается и разрабатывается аппаратное обеспечение, а затем программное обеспечение должно заставить его работать. Если плата работает не так, как ожидается, или плату изменили таким образом, что она перестала работать, как правило, ожидается, что проблема будет решена с помощью доработки программного обеспечения. В этом смысле разработчики встроенного ПО чем то похожи на хакеров.
«Важно поддерживать синхронизацию процесса разработки встроенного программного обеспечения с процессом разработки плат прототипов».
Ключом к реализации программы прототипирования является эффективное управление и тесная совместная работа разработчиков программного и аппаратного обеспечения. Это часто становится проблемой даже в крупных компаниях и может быть реальным фактором риска для небольших стартапов. Очень важна роль руководителя проекта, который должен понимать технические проблемы и уметь работать с людьми. Дизайн-ревью после каждого этапа прототипирования должны стать не просто формальными мероприятиями, а реальным обсуждением проблем и предложенных способов решения. Правильное управление процессом разработки является ключом к успешной программе создания прототипов.
Небольшое дополнение к статье от Алекса Элиума
Рекомендации по выбору языка для программирования встраиваемых систем
«Прямо сейчас, я настоятельно рекомендую использовать C++, хотя мир встраиваемых решений быстро меняется, и в течение нескольких лет мы, возможно, будем использовать виртуальные машины на основе Java или Python».
C++ - отличный выбор языка программирования для создания встроенного программного обеспечения. Раньше этот язык не мог конкурировать с C, так как для C++ просто не хватало оперативной памяти/Flash. Теперь это не так. Если вы, конечно, не разрабатываете очень массовый продукт, разница в себестоимости между контроллерами с 200 КБ ОЗУ и 20 КБ ОЗУ вряд ли будет так заметна, как потенциальная экономия от сокращения времени разработки.
Вот несколько моментов, которые стоит учитывать, если вы используете C++:
- Не используйте динамическую идентификацию типов данных (RTTI) и Exceptions
- С большой осторожностью используйте STL. String, vector, map, queue и несколько других контейнеров стоят того, чтобы под них была выделена оперативная память. К тому же, хороший компилятор при использовании оптимизированных библиотек сведет вклад этих типов к минимуму. Например, «short string optimization» может сделать использование памяти std::string эквивалентным C-строке. Избегайте более "тяжелых" библиотек, таких как regex - они, вероятно, излишни. и их неиспользуемые функции займут место во Flash.
Имейте ввиду, что мир встраиваемых решений быстро меняется, особенно когда крупные игроки отрасли проявляют интерес к IoT. В конце концов мы, возможно, будем использовать что-то типа виртуальной машины на основе Java или Python. На всякий случай, уже сейчас стоит взглянуть на MicroEJ, embedded Java IDE и VM, и MicroPython.
Независимо от того, какой язык вы используете, нужно обратить внимание на автоматическое тестирование и выбор некоей процессорно-независимой операционной системы реального времени (RTOS), такой как mBed, FreeRTOS или Zephyr. RTOS позволит вам изменять процессоры без особых проблем. Автоматизированные тесты, на уровне модуля или системы, позволят вам быстро проверить код при выпуске нового прототипа.
Следующие шаги
В следующей статье этого цикла будет рассказано, как разработать и выполнить успешную программу создания прототипов, чтобы достичь успеха на рынке.