Общие сведения
Вы собираетесь написать «bare-metal»-программу на Rust для микроконтроллера, то есть без операционной системы. Возможно, вы никогда раньше ничего подобного не делали. Это замечательно — добро пожаловать в увлекательное приключение!
Для начала ответим на несколько базовых вопросов, которые могут у вас возникнуть.
-
Что такое микроконтроллер?
Микроконтроллер — это система на кристалле. Ваш компьютер состоит из нескольких отдельных компонентов: процессора, оперативной памяти, накопителя, порта Ethernet и т. д. А в микроконтроллере все такие компоненты объединены в одном «чипе» или корпусе. Благодаря этому системы можно строить из меньшего числа деталей.
-
Что можно делать с помощью микроконтроллера?
Очень многое! Микроконтроллеры — основа так называемых «встраиваемых систем». Встраиваемых систем вокруг очень много, но вы обычно их не замечаете. Они управляют машинами, которые стирают одежду, печатают документы и готовят еду. Встраиваемые системы поддерживают комфортную температуру в зданиях, где вы живёте и работаете, и управляют узлами транспортных средств, благодаря которым вы едете и останавливаетесь.
Большинство встраиваемых систем работает без вмешательства пользователя. Даже если у них есть интерфейс, как у стиральной машины, основную работу они выполняют самостоятельно.
Встраиваемые системы часто используются, чтобы управлять физическим процессом. Для этого у них есть одно или несколько устройств, которые сообщают о состоянии окружающего мира («датчики»), и одно или несколько устройств, с помощью которых они что-то меняют («исполнительные механизмы»). Например, система климат-контроля здания может включать:
- Датчики, которые измеряют температуру и влажность в разных точках.
- Исполнительные механизмы, которые регулируют скорость вентиляторов.
- Исполнительные механизмы, которые добавляют тепло в здание или отводят его.
-
Когда стоит использовать микроконтроллер?
Многие из перечисленных выше встраиваемых систем можно было бы реализовать на компьютере под управлением Linux (например, на «Raspberry Pi»). Зачем тогда использовать микроконтроллер? Похоже, что программу для него разрабатывать сложнее.
Вот некоторые причины:
-
Стоимость: микроконтроллер гораздо дешевле компьютера общего назначения. Причём он не только дешевле, но и требует намного меньше внешних электронных компонентов для работы. Благодаря этому печатные платы (PCB) получаются меньше и дешевле и в проектировании, и в производстве.
-
Энергопотребление: большинство микроконтроллеров потребляет лишь малую долю энергии полноценного процессора. Для устройств, работающих от батарей, это огромная разница.
-
Отзывчивость: для выполнения своей задачи некоторым встраиваемым системам нужно всегда реагировать в ограниченный промежуток времени (например, антиблокировочная система тормозов автомобиля). Если система не уложится в такой срок, может произойти катастрофический отказ. Такое требование называют «жёстким реальным временем» (hard real time), а встраиваемую систему, которая связана таким сроком, — «системой жёсткого реального времени». У компьютера общего назначения с ОС обычно много программных компонентов, которые делят между собой вычислительные ресурсы. Из-за этого труднее гарантировать выполнение программы в жёстких временных рамках.
-
Надёжность: в системах с меньшим числом компонентов (как аппаратных, так и программных) меньше возможностей для сбоя!
-
-
Когда не стоит использовать микроконтроллер?
Микроконтроллеры часто плохо справляются с тяжёлыми вычислениями. Чтобы стоимость и энергопотребление оставались низкими, у микроконтроллеров ограничены вычислительные ресурсы.
Микроконтроллеры обычно выполняют меньше инструкций в секунду, чем «большие» процессоры. Самые медленные из них могут работать «всего лишь» на нескольких миллионах инструкций в секунду. Кроме того, полезной работы на одну инструкцию, как правило, выполняется меньше. Микроконтроллеры обычно 32-битные, но 16-битные встречаются нередко: из-за этого для работы с привычными типами данных Rust может понадобиться больше инструкций. У большинства микроконтроллеров нет или почти нет «кэша», поэтому инструкции выполняются ровно настолько быстро, насколько быстро доступна основная память.
Некоторые микроконтроллеры не имеют аппаратной поддержки операций с плавающей точкой. На таких устройствах сложение двух чисел одинарной точности может занять сотни тактов процессора.
Наконец, памяти у микроконтроллеров обычно немного. Её может быть всего 16 КБ для инструкций программы и 4 КБ для данных, что делает программирование для таких систем довольно непростым. Объём встроенной памяти на единицу стоимости и энергопотребления постоянно растёт, но процессор, с которым мы будем работать, по-прежнему располагает «всего лишь» 512 КБ памяти для инструкций и 128 КБ для данных — гораздо меньше, чем у «настоящего компьютера».
-
Почему Rust, а не C?
Надеюсь, убеждать вас тут не придётся: вы, вероятно, знакомы с различиями между Rust и C. Хочу отдельно отметить управление пакетами. У C нет официального и широко принятого решения для управления пакетами, а у Rust есть Cargo. Благодаря этому разработка становится заметно проще. А ещё, по моему мнению, удобное управление пакетами поощряет повторное использование кода: библиотеки легко подключаются к приложению, а это хорошо, потому что библиотеки получают больше «боевой проверки».
-
Почему не стоит использовать Rust?
Или почему стоит предпочесть C Rust’у?
Экосистема C более зрелая. Для многих задач уже есть готовые решения. Если нужно управлять процессом, чувствительным ко времени, можно взять одну из существующих коммерческих операционных систем реального времени (RTOS) и решить задачу. Коммерческих RTOS промышленного уровня на Rust (на момент написания) нет, поэтому придётся либо создать такую систему самим, либо попробовать одну из тех, что находятся в разработке. Список таких проектов есть в репозитории Awesome Embedded Rust.