программирование микроконтроллеров против объектно-ориентированного программирования


11

Я сделал несколько базовых объектно-ориентированных программ на C ++ (создание B-дерева, алгоритмов хеширования, двойных связанных списков) и небольшой проект на C (например, создание научного калькулятора и т. Д.).

Насколько аппаратное программирование (особенно для микроконтроллеров) отличается от программного / объектно-ориентированного программирования с точки зрения мышления и «мышления», которое должен иметь программист?

Один из них обычно считается сложнее, чем другие мои самые люди?

С моим опытом (как описано выше) мне нужно было бы много подготовиться к изучению аппаратного программирования или я мог бы погрузиться прямо в это без особой подготовки?


4
Самая большая кривая обучения будет о том, как управлять конкретным оборудованием в вашем микро. Это будет включать в себя изучение листов данных в течение нескольких часов. К сожалению, нет легкого выхода.
drxzcl

@rrazd, я заметил, что вы включили тег arduino. Это потому, что вы хотите использовать язык и библиотеки проводки arduino? Или вы будете писать свои встроенные приложения на чистом C? Если вы намереваетесь придерживаться среды Arduino, играть в нее довольно безопасно и легко, так как они сделали некоторые абстракции от аппаратного обеспечения.
Джон Л

@Jon я планирую использовать доску Arduino для начинающих. Разве это не похоже на язык Си? Я думал, что это включает в себя те же основные понятия ....
Разд

1
Мне интересно, имеете ли вы в виду то, что многие называют «программированием ввода / вывода», или вы ожидаете переупорядочения аппаратного обеспечения с помощью кода. Arduino определенно является первым; последний будет доменом ПЛИС.
JustJeff

1
@rrazd - я сменил название; «аппаратное программирование» звучит слишком похоже на HDL (Hardware Description Language), например, VHDL и Verilog, которые используются для программирования FPGA и CPLD.
Стивенвх

Ответы:


10

При работе с большинством микроконтроллеров вам придется полностью отказаться от объектно-ориентированной парадигмы.

Микроконтроллеры, как правило, ограничены регистром и оперативной памятью, с низкой тактовой частотой и без конвейерного / параллельного кода. Вы можете забыть о Java на PIC, например.

Вы должны войти в мышление на ассемблере и писать процедурно.

Вы должны держать свой код относительно плоским и избегать рекурсии, так как ограничения ОЗУ часто могут привести к проблемам со стеком.

Вы должны научиться писать эффективные процедуры обработки прерываний (обычно на ассемблере).

Возможно, вам придется выполнить рефакторинг частей кода вручную на языке ассемблера, чтобы реализовать функциональные возможности, которые компилятор не поддерживает (или плохо поддерживает).

Вы должны написать математический код, который учитывает размер слова и отсутствие возможностей FPU большинства микроконтроллеров (то есть выполнение 32-битного умножения на 8-битном микро = зле).

Это другой мир. Для меня наличие компьютерных или профессиональных навыков программирования может быть такой же помехой, как и отсутствие знаний при работе с микроконтроллерами.


1
Вам не нужно полностью отказываться от объектно-ориентированной парадигмы, но на небольших микросхемах может возникнуть необходимость отказаться от реализации тяжелых объектов и по-настоящему задуматься о том, как лучше решить каждую проблему. Часто это процедурные, но легкие объекты, хорошо реализованные (обычно вручную), иногда могут уменьшить размер сложных проектов микроконтроллера.
Крис Страттон

6
Все это верно, кроме отказа от объектной ориентации. Вы, вероятно, не будете использовать язык с функциями ОО, но это не исключает ориентации объекта. Для микроконтроллеров вы собираетесь написать драйверы для всех аппаратных периферийных устройств (АЦП, контроллеров последовательной шины, ШИМ и т. Д.). Такой драйвер всегда должен быть написан объектно-ориентированным образом, чтобы он был 1) автономным и не знал / не заботился об остальной части программы, и 2) реализовывал приватную инкапсуляцию, чтобы остальная часть программы не могла иди и возни с этим. Это на 100% возможно в C и не повлияет на производительность.
Лундин

1
Я категорически не согласен с первым предложением, все мои проекты микроконтроллеров были построены с использованием C ++ и объектно-ориентированного подхода, а используемые нами микросхемы были не очень большими (32 КБ ПЗУ), а также объектно-ориентированный загрузчик занимал менее 2 КБ. на самом деле не вижу ограничений. Вы не можете делать сумасшедшие вещи, но дизайн может быть объектно-ориентированным без проблем.
Арсенал

@ Арсенал Заметьте, что я сказал «большинство», и обратите внимание, что вы комментируете четырехлетнюю ветку. :)
Адам Лоуренс

Я полностью не согласен с первым и последним предложением. А также сборка используется довольно редко и, в основном, только для 8-битных микроконтроллеров (просто проверьте этот форум, сколько постов с кодом сборки вы можете найти?). Вы наверняка можете и (ИМХО) написать в ОО стиле для 32-
битных

10

Вам нужно подумать о нескольких вещах:

  • Вы будете использовать C в качестве языка
  • Вы все еще можете создать ощущение ориентации объекта, используя указатели функций, чтобы вы могли переопределять функции и т. Д. Я использовал этот метод в прошлых и текущих проектах и ​​работает очень хорошо. Так что ОО частично есть, но не в смысле С ++.

Существуют и другие ограничения, такие как ограниченная скорость и память. Так что в качестве общего руководства я избегаю:

  • Используя кучу, если есть способ решить проблему без Malloc, я делаю это. Например, я предварительно выделяю буферы и просто использую их.
  • Я намеренно уменьшаю размер стека в настройках компилятора, чтобы с самого начала столкнуться с проблемами размера стека, тщательно оптимизирую его.
  • Я предполагаю, что каждая отдельная строка кода будет прервана событием, поэтому я избегаю не повторяющегося кода
  • Я предполагаю, что даже прерывания вложены, поэтому я пишу этот код соответственно
  • Я избегаю использования ОС, если это необходимо. 70% встроенных проектов на самом деле не нуждаются в ОС. Если я должен использовать ОС, я использую только то, что доступно с исходным кодом. (Freertos и т. Д.)
  • если я использую ОС, я почти всегда абстрагируюсь, чтобы сменить ОС за считанные часы.
  • Для драйверов и т. Д. Я буду использовать только библиотеки, предоставленные поставщиком, я никогда не буду напрямую возиться с битами, если у меня нет другого выбора. Это делает код читабельным и улучшает отладку.
  • Я смотрю на циклы и другие вещи, особенно в ISR, чтобы убедиться, что они достаточно быстрые.
  • Я всегда держу под рукой несколько GPIO для измерения, переключения контекста, времени работы ISR и т. Д.

Список можно продолжить, я, вероятно, ниже среднего с точки зрения программирования, я уверен, что есть лучшие практики.


3
+1 за «вы можете использовать ОО парадигмы, если хотите». То, что вам нужно проверить на двери, не дизайн OO. OOD - это просто философия, которая призывает вас хранить связанный код и данные вместе. То, что вам нужно оставить, - это способ реализации ОО в корпоративных системах с несколькими уровнями абстракции, инверсией управления и всем этим джазом. Задача вашей прошивки состоит в том, чтобы управлять оборудованием, вот и все.
drxzcl

7

Я делаю оба, так что вот мое мнение.

Я думаю, что самый важный навык на данный момент во встроенных системах - это ваша способность к отладке. Требуемое мышление сильно отличается тем, что гораздо больше может пойти не так, и вы должны быть очень открыты, чтобы рассмотреть все различные пути, которые вы пытаетесь сделать, могут пойти не так.

Это самая большая проблема для новых разработчиков встраиваемых систем. Люди с ПК, как правило, имеют более грубый характер, поскольку привыкли к тому, что просто работают на них. Они будут тратить много времени на поиски инструментов, которые вместо этого будут делать что-то для них (подсказка: их немного). Снова и снова бьют головы в стены, не зная, что еще делать. Если вы чувствуете, что застряли, отойдите назад и выясните, сможете ли вы определить, что все может пойти не так. Систематически проходите сужение списка потенциальных проблем, пока не разберетесь. Из этого процесса непосредственно следует, что вы должны ограничить объем проблем, не меняя слишком много сразу.

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

Вы работаете над кодом, который выполняется на внешней системе вашей системы разработки, с различной степенью видимости вашей цели от платформы к платформе. Если вы находитесь под вашим контролем, ищите средства для разработки, которые помогут улучшить эту видимость вашей целевой системы. Используйте отладочные последовательные порты, отладочные выходные данные с разбивкой битов, знаменитый мигающий свет и т. Д. Конечно, как минимум узнайте, как использовать осциллограф, и используйте вывод ввода-вывода с областью действия, чтобы видеть, когда определенные функции входят / выходят, ISR срабатывает и т. Д. Я наблюдал, как люди боролись буквально на годы дольше, чем необходимо, просто потому, что они никогда не удосужились настроить / научиться использовать правильную ссылку отладчика JTAG.

Гораздо важнее точно знать, какие именно ресурсы у вас есть по отношению к ПК. Внимательно прочитайте таблицы. Подумайте о ресурсной «стоимости» всего, что вы пытаетесь сделать. Изучите ориентированные на ресурсы приемы отладки, такие как заполнение стекового пространства магическим значением для отслеживания использования стека.

Хотя для ПК и встроенного программного обеспечения требуются определенные навыки отладки, для встроенных это гораздо важнее.


5

Я предполагаю, что ваш опыт C ++ основан на ПК.

Программисты, часто переходящие с ПК на микроконтроллер, часто допускают ошибку, заключающуюся в том, что они не понимают, насколько ограниченными могут быть ресурсы . На ПК никто не остановит вас, когда вы создадите таблицу с 100 000 записей или напишите программу, которая составляет 1 МБ машинного кода.
Там являются микроконтроллеры , которые имеют огромное количество ресурсов памяти, особенно в высоком конце, но это еще далеко от того, что вы привыкли. Для хобби-проекта вы, вероятно, всегда можете пойти на максимум, но в профессиональном проекте вам часто придется работать с меньшим устройством, потому что оно дешевле . Над
одним проектом я работал с TI MSP430F1101, 1 КБ памяти программ, 128 байтов конфигурации Flash, 128 байтов оперативной памяти. Программа не помещалась в 1K, поэтому мне пришлось написать 23-байтную функцию в конфигурации Flash. С этими маленькими контроллерами вы вычисляете по байту . В другой раз память программы была слишком маленькой на 4 байта. Босс не позволил бы мне использовать контроллер с большей памятью, но вместо этого мне пришлось оптимизировать уже оптимизированный машинный код (он уже был написан на ассемблере), чтобы вместить дополнительные 4 байта.

В зависимости от платформы, с которой вы работаете, вам придется иметь дело с очень низким уровнем ввода-вывода . Некоторые среды разработки имеют функции для записи на ЖК - дисплее, но и на других , вы сами по себе, и будет читать ЖК-дисплея технический паспорт от начала до конца , чтобы узнать , как управлять им.
Возможно, вам придется управлять реле, это проще, чем ЖК-дисплей, но для этого потребуется перейти на уровень регистров микроконтроллера. Снова таблица данных или руководство пользователя. Вам нужно будет узнать структуру микроконтроллера, которую вы найдете в блок-диаграмме, снова в таблице данных. Во времена микропроцессора мы говорили о модели программирования, который был в основном линейкой регистров процессора. Современные микроконтроллеры настолько сложны, что описание всех регистров может занять большую часть таблицы на 100 страниц. IIRC просто описание модуля часов для MSP430 было 25 страниц в длину.

μ

Микроконтроллеры часто запрограммированы в C . C ++ довольно требователен к ресурсам, поэтому его обычно нет. (Большинство реализаций C ++ для микроконтроллеров предлагают ограниченное подмножество C ++.) Как я уже сказал, в зависимости от платформы у вас может быть обширная библиотека доступных функций, которая может сэкономить вам некоторое время на разработку. Стоит потратить некоторое время на его изучение, это может сэкономить вам много времени позже, если вы знаете, что доступно.


Я написал игры для Atari 2600, которая является довольно ограниченной платформой; моя первая опубликованная игра была, по сути, 4K-кодом (поскольку у меня была корзина 32K, я добавил несколько дополнительных вкусностей, но 4K-версия была полностью играбельной); Объем оперативной памяти составляет 128 байт. Мне интересно созерцать, что в год, когда я написал эту игру (2005), были выпущены другие игры, которые были буквально в миллион раз больше.
суперкат

@supercat - Да, но этого следовало ожидать, в 2005 году Atari 2600 было уже 200 лет! Я никогда не играл в экшн-игры, такие как FPS, но когда я смотрю на то, что нужно для них, на графический процессор, намного более мощный, чем ваш процессор, как программно, так и электрически, я не могу не покачать головой :-). Я играл в шахматы (Саргон) на 16K TRS-80 IIRC. Симулятор полета моего брата больше не нуждался.
Стивенвх

Не совсем 200 лет. Это дебютировало в 1977 году, так что даже не было 30. Хотя я согласен с тем, что это было целую вечность в технологическом плане, я все еще поражен тем фактом, что нет ни увеличения сотен трюмов, ни увеличения в тысячу раз , но в МИЛЛИОНОМ увеличении как RAM, так и размера кода. Скорость не сильно возросла, поскольку частота 2600 была равна 1,19 МГц, а новые системы работают только в диапазоне низких частот. Они могут делать намного больше за цикл, чем 2600 (которые могли - и должны были - генерировать 1/76 видеолинии в каждом цикле), но я не думаю, что они в 1 000 000 раз быстрее.
суперкат

3

«аппаратное программирование» может означать много вещей. Программирование очень маленькой микросхемы (например, 10F200, 512 инструкций, несколько байтов ОЗУ) может быть похоже на проектирование электронной схемы. С другой стороны, программирование большого микроконтроллера Cortex (1 МБ FLASH, 64 КБ ОЗУ) может быть очень похоже на программирование ПК / GUI с использованием большого инструментария GUI. ИМХО, хороший программист встраиваемого / реального времени нуждается в навыках как со стороны разработки программного обеспечения, так и со стороны проектирования схем. Для больших uC C ++ - хороший выбор языка, для очень маленьких - C может быть единственным выбором. Знание ассемблера может быть полезным, но я бы не советовал делать серьезные проекты полностью в сборке.

Я сделал серьезную встроенную работу с людьми с обеих сторон (SWI и EE). Я обычно предпочитаю людей SWI, при условии, что у них есть некоторый опыт многопоточного программирования.

Ваш вопрос звучит так, будто вы хотите погрузиться во встроенное программирование. Во что бы то ни стало сделайте это. Что касается низкоуровневых аспектов (сопряжения периферийных устройств в вашем чипе и оборудования вокруг него), вам необходимо освоить некоторые новые навыки, но это просто большая работа без многих новых концепций. Для более высоких уровней ваших проектов вы можете использовать существующие знания.


1

Для каждого метода библиотеки arduino, который вы вызываете, существует множество C / C ++ кода, который делает это возможным, его просто удобно упаковывать для использования в качестве API. Взгляните на исходный код arduino в каталоге hardware / arduino / *, и вы увидите все написанные для вас C / C ++, которые напрямую взаимодействуют с регистрами микроконтроллера AVR. Если ваша цель состоит в том, чтобы научиться писать такие вещи (непосредственно для оборудования), то есть что рассказать. Если ваша цель состоит в том, чтобы заставить что-то работать с использованием их библиотек, тогда не о чем говорить, поскольку большая часть тяжелой работы сделана для вас, а их библиотеки и среда разработки очень просты в использовании.

Некоторые практические правила при работе с устройствами с ограниченными ресурсами, которые могут применяться к среде Arduino или другим:

Знайте, сколько памяти вы используете. И размер кода (который идет во флэш-память) и статическое использование ОЗУ (константы в вашем коде, которые всегда будут существовать в ОЗУ). Я бы сказал, что использование статической оперативной памяти немного важнее, так как ее легко просмотреть. Нередко у вас есть только 1000 байтов для работы со стеком, кучей и константами. Будьте мудры в том, как вы их тратите, поэтому избегайте таких вещей, как длинные массивы целых чисел (по 4 байта каждый), когда будет достаточно байтов или символов без знака (по 1 байту каждый). Другой ответ здесь очень хорошо описывает некоторые другие важные моменты, поэтому я остановлюсь здесь, я в основном хотел бы подчеркнуть, что есть много чего, если вы не используете библиотеку arduino и не пишете свои собственные библиотеки C.


0

Что касается микроконтроллера и ООП программирования, они не являются чем-то противоположным. Это правда, что все библиотеки вендоров находятся в простом C, но все платформы также поддерживают C ++ OOP. Разработчики могут создавать и создавать высокоуровневые библиотеки C ++ и встроенное ПО для устройств. Хороший пример - библиотеки Arduino, официальные и пользовательские - в основном классы C ++. Возможно, не все преимущества ООП могут быть полностью использованы во встроенной среде, но хорошо известные здесь преимущества C ++ и C также применимы.

Что касается мышления и мышления, как отмечалось в других ответах, микроконтроллеры - это платформы с очень ограниченными ресурсами (особенно в оперативной памяти, с меньшей скоростью) - такие вещи, как динамическое распределение памяти, исключения C ++ обычно исключаются. Учитывая, что выбрано правильное оборудование, эти ограничения легко принять и использовать другие методы (также широко используемые в других платформах).

На мой взгляд, более сложной задачей может быть еще одно дополнительное измерение во встроенном программировании - синхронизация. Это связано с тем, что обычно встроенное программное обеспечение в значительной степени связано с событиями в реальном времени, строго синхронизированными протоколами для управления периферийным оборудованием и самой общей задачей (это некоторые параллели и в других «высокоуровневых» платформах, таких как многопоточные приложения).

Будьте готовы прочитать много таблиц при работе с новым оборудованием - думаю, это может быть связано с вопросом о «мышлении» :) Конечно, потребуются некоторые знания в области ЭЭ и аппаратного обеспечения.

Также я хотел бы отметить, что в наши дни разработка встроенного программного обеспечения не требует ассемблера. На самом деле Java (кстати, по умолчанию это ООП) уже здесь и становится сильнее (по крайней мере, для некоторых классов встраиваемых устройств, например IoT-устройств, у нее может быть очень светлое будущее).


С точки зрения проблем, вопросы, связанные с динамическим (пере) распределением памяти, имеют тенденцию быть большим препятствием для традиционного ОО, чем синхронизация .
Крис Страттон

Возможно, вы правы. Но есть люди, которые программировали в 80-90-х годах для программного обеспечения реального режима MSDOS, с доступным объемом оперативной памяти 64 КБ (сегмент памяти данных), и для них это было "естественно". Может быть, ПК MSDOS был более «встроенной» средой, чем сегодняшние STM32F4 :)
Фланкер

STM32F4 обычно имеет больше программной памяти в виде флэш-памяти, но ПК обычно имеет гораздо больше оперативной памяти для хранения изменяемых объектов времени выполнения. Несмотря на то, что вся работа с дальним указателем, вызванная сегментированной адресацией, была болью, у обоих нет настоящего MMU, и это будет еще большей проблемой для системы с меньшим объемом ОЗУ, которым является STM32F4. Также время простоя ПК было меньше, а допустимая частота отказов выше.
Крис Страттон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.