Язык программирования Си в микроконтроллерах. Общие сведения, плюсы и минусы использования.

Язык программирования Си.

Введение

Основой любого микроконтроллерного устройства является заложенная в него программа. Она задает алгоритм функционирования устройства, последовательность действий, связывает входы и выходы в единую систему. Что собой представляет эта программа? Это просто набор команд в машинных кодах микроконтроллера, заботливо созданный компилятором. Читать программу в таком виде нереально, а писать тем более (хотя в юности автор баловался с ручным переводом программ в маш. коды для Z-80, но это скорее от избытка времени, нежели от большого ума). Поэтому пионеры компьютерной науки разработали языки программирования и их трансляторы, самым первым из которых был ассемблер. Ассемблер – язык низкоуровневый, команды по сути обозначают те же коды процессора в более удобочитаемом виде (мнемоники).  Тем не менее, он имеет все возможности для описания любых алгоритмов (если у их составителей хватит на это терпения), причем выполняться они будут максимально быстро. Но есть недостатки – долгое время разработки, отладки – попробуй, разберись в тысячах строках текста и в сотнях переходах с метки на метку. В таком случае не спасает даже структуризация кода, а со сменой платформы, приходится переписывать много кода из-за жесткой привязки к машинным кодам процессора. Чтобы исправить эти проблемы, были придуманы языки программирования высокого уровня – начиная с Фортрана, Кобола и заканчивая современными Си++, Java и т.п. Одним из них является рассматриваемый в статье Си.   Си был создан для написания операционной системы Unix вначале 70-х. Получился близким к ассемблеру по быстродействию (максимально близок по быстродействию из почти всех языков), но намного удобнее в применении. Он оказался настолько удачным, что получил широкое применение и под его влиянием были созданы те же Си++/Си# и Java.

История микроконтроллеров началась позже истории компьютеров, но пошла по тому же пути – после царствования ассемблера, появилась возможность использовать более сложные языки – Бейсик, Паскаль, Си и даже графические – FlowCode и Algorithm Builder. Все они несложны в освоении и позволяют быстро начать разработку, тут выбор остается за каждым. Но в защиту Си необходимо добавить: он стандартизирован – для всех устройств одинаков, работает на большом числе платформ; зная его можно освоить в будущем Си++ или Си# и писать утилиты для ПК (например для управления устройством с компьютера); в будущем поможет при переходе на более серьезные платформы – ARM или FPGA(близок к Verilog). А вот Бейсик для МК мало похож на его современный компьютерный вариант Visual Basic и в дальнейшем малопригоден, а при неструктурном применении еще и вреден (в чем убедился автор, переучиваясь с трудом с Бейсика на Си).

Программисты на Си

Рассмотрим тех людей, которые приходят к необходимости изучения Си для микроконтроллеров.

1)    Новички:

– чистые программисты, пришедшие в мир электроники по разным причинам, для них софтовые проблемы и реализация алгоритмов не составляет труда, но вот аппаратные нюансы вызывают большие трудности. Они легко могут работать с ассемблером, но зачем отказывать себе в более быстром и удобном инструменте;

–  электронщики (и просто радиолюбители) – люди противоположные первым, легко составляют схемы, разводят платы, но программирование для них дается нелегко. Да, ассемблер близок к аппаратной части, но писать на нем начинающим программистам не так просто, нежели на Си;

– любители – новички во всем, те, кто со школы или университета еще помнят, что такое сопротивление и емкость, изучали на информатике Бейсик или Паскаль. Им будет тяжело во всем, и скорее всего первым их языком будет Бейсик, Паскаль, либо графический. Но если такой человек устремится к совершенствованию, то тут ему уже не обойтись без более глубоких знаний что, в конце концов, приведет к необходимости изучения Си. Кстати стоит упомянуть любителей Ардуино – программы там пишутся на Си, но система встроенных библиотек такова, что быстродействие принесено в жертву скорости разработки.

2)    Профессионалы: это либо программисты встраиваемых систем, либо бывшие новички, кто продвинулся в навыках. Все они используют ассемблер по максимуму, особенно в случаях, когда без него не обойтись (очень компактные программы, мало-ресурсные системы, участки программы критичные к быстродействию). Но для более сложных устройств, ускорения производства кода и отладки, увеличения функциональности наступает пора перехода на высокоуровневые языки – прежде всего Си (причем в ARM системах проще сразу начинать с него).

Почему выбирают Си? Разберем достоинства и недостатки этого языка по отношению к ассемблеру для микроконтроллеров.

Достоинства

1)    Простота изучения. Освоить базу языка не составит никакого труда. Для этого достаточно понять реализацию основных составляющих алгоритма – условие, цикл, выбор (case-switch), логические и арифметические операции и можно приступать к работе.

2)    Скорость разработки. Более высокий уровень позволяет намного проще реализовывать функциональность.

3)    Лучшие возможности для составления сложных программ, которые обеспечиваются применением структурного подхода к проектированию программ. Программа разбивается на отдельные завершенные логические блоки – функции и процедуры, которые могут объединяться в библиотеки.  Разработка идет «сверху в низ» от логики работы алгоритма в целом к функционированию отдельных узлов, что позволяет проводить отладку уже на ранних стадиях. Язык устроен так (и создавался для того), чтобы избежать использования оператора goto, намного облегчая чтение и отладку.

4)    Большое число готовых библиотек, примеров, статей и книг.

5)    Как было отмечено выше – язык стандартизирован (изучить придется один раз), перспективен для будущего развития разработчика.

Недостатки

1)    Сложность углубленного изучения. Придется много читать, смотреть форумы, покопаться в исходниках идущих в комплекте библиотек. При дальнейшем продвижении в изучении можно столкнуться с множеством трудностей, но решение их заметно расширяет возможности программиста. Например – составление универсальных библиотек с условной компиляцией, применяя которые можно менять целевой микроконтроллер или состав устройства, практически не переписывая код.

2)    Отдаленность от аппаратной части. Ассемблер требует четкого знания принципа работы микроконтроллера, времени выполнения команд, позволяет самому выбирать какие переменные оставить в регистрах, а какие разместить в ОЗУ. Си же абстрагирует от платформы. Время выполнения можно оценить, обладая только определенным опытом (просматривая в дизассемблере созданный код). А уж размещение переменных компилятор берет на себя – чаще всего в ОЗУ, используя регистры только для временных данных (если не указывать специально модификаторы register или volatile с резервируемым регистром). Получается черный ящик, который создает правильно функционирующую программу – но что в ней происходит точно, ответить будет не просто. Стоит учесть, что современные компиляторы  хорошо оптимизированы и выдают хороший код. Но для серьезных разработок все равно нужно представлять, как работает МК и знать ассемблер.

3)    Увеличение объема кода. Почти всегда код на Си будет занимать больше места при одинаковом алгоритме работы. Причины все те же – в компиляторе,  так как генерация кода с более высокоуровневого языка вызывает дополнительные расходы на реализацию операций, недоступных в самом ассемблере.

4)    Снижение производительности. Си называют «ассемблером высокого уровня», что говорит о большой скорости выполнения программ. Но некоторое падение производительности происходит. Это зависит от эффективности компилятора, происходит при генерации прошивки с оптимизацией по размеру кода, существуют накладные расходы (например, начальное обнуление регистров и ОЗУ). Несмотря на это для большинства задач применения МК разницы между Си и ассемблером в производительности не будет сильно заметно.

5)    Накладываются ограничения связанные с простой АЛУ, малым числом ресурсов и низкой разрядностью. Необходимо аккуратно задавать типы переменных, все, что выше 1 байта – 2 и 4 байтные целые уже вычисляется в несколько циклов, а вещественные переменные и вовсе десятки циклов. Во многих МК нет аппаратного умножения, компилятор заменяет его циклическим сложением. В особо мелких МК стек аппаратный, число вложений подпрограмм ограничено. Также маловато ОЗУ. В таком случае выгоднее использовать ассемблер.

6)    Возможно непонимание кода, написанного другими программистами. Проводя оптимизацию или просто в силу наработанных привычек, они могут применять тяжело воспринимаемые инструкции. Например: копирование строк while(*dst++ = *src++);

7)    Есть вероятность появления плохо отлавливаемых ошибок: утечка памяти, обращение к элементу массива по индексу, лежащему вне его границы, неправильные операции над указателями. Это связано со слабым пониманием работы с указателями, с динамическим выделением памяти. Поэтому нужно внимательнее изучить эти темы.

Выводы

Довольно много минусов набралось. Но если посмотреть внимательно, то почти все указанные недостатки устраняются с увеличением опыта работы. Зато достоинства дают хорошее преимущество, ускоряя разработку и экономя драгоценное время.

Для новичков автор рекомендует начать с изучения Си, параллельно почитывая об аппаратной части МК, системе команд контроллера. Более-менее освоив язык, можно будет взяться за ассемблер, знание которого поможет в оптимизации программ. Электронщикам следует поступить также. А вот профессиональным программистам будет легко сделать выбор самим.

P.S.

Язык программирования лишь инструмент в руках программиста. Поэтому опытные программисты чаще выбирают его под задачу, а начинающие все пытаются сделать на одном языке. В этом случае Ассемблер и Си можно сравнить между собой как лобзик и набор пил (от мелкой до бензопилы). Если необходимо проделать тонкую работу, особой изящности от пилы не стоит ожидать – придется ошлифовывать углы. Но если дело в постройке дома, то лобзиком тут пилить, не перепилить (вот когда дом построил, там уж можно резные оконца придумать). Большое значение имеет еще владение инструментом (есть умельцы которые и пилой узоров понаделают). Отсюда возникают советы программистам МК: изучайте асм и Си, они хорошо дополняют друг друга; совершенствуйте свои навыки, больше практикуйтесь, читайте чужой код и анализируйте, все это только в пользу.

Оцените статью
Добавить комментарий

  1. crus07

    Автору благодарность за статью

    Ответить