програмування мікроконтролерів проти об'єктно-орієнтованого програмування


11

Я зробив декілька базових об'єктно-орієнтованих програмувань за допомогою C ++ (створення B-дерева, алгоритмів хешингу, подвійних зв'язаних списків) і зробив невеликий проект на C (наприклад, виготовлення наукового калькулятора тощо)

Наскільки відрізняється апаратне програмування (спеціально для мікроконтролерів) від програмно-об’єктно-орієнтованого програмування з точки зору мислення та «мислення», яке повинен мати програміст?

Чи вважають одного, як правило, важчим за інших моїх людей?

З моїм досвідом (як описано вище) мені знадобиться велика підготовка до того, щоб перейти до апаратного програмування, чи можу я зануритися прямо без зайвої підготовки?


4
Найбільшою кривою навчання буде те, як керувати конкретним обладнанням у вашому мікрофоні. Це передбачає перенесення інформаційних аркушів протягом годин. На жаль, не існує простого виходу.
drxzcl

@rrazd, я помітив, що ви включили тег arduino. Це тому, що ви хочете використовувати мову проводки arduino та бібліотеки? Або ви будете писати свої вбудовані програми у чистому С? Якщо ви маєте намір дотримуватися середовища arduino, це досить безпечно і легко грати, оскільки вони робили деякі абстракції подалі від обладнання.
Джон Л

@Jon я планую використовувати ардуїно дошку для початківців. Хіба це не схоже на мову С? Я думав, що це стосується тих самих основних понять ....
rrazd

1
Мені цікаво, чи ви маєте на увазі те, що багато людей називали б «програмування вводу-виводу», чи ви очікуєте перевпорядкування обладнання з кодом. Ардуїно, безумовно, колишній; останнє було б доменом FPGA.
JustJeff

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

Відповіді:


10

Вам доведеться повністю відмовитися від об'єктно-орієнтованої парадигми, коли маєте справу з більшістю мікроконтролерів.

Мікроконтролери, як правило, обмежені реєстрацією та оперативною пам'яттю, з повільною тактовою частотою та відсутністю конвеєрних / паралельних кодових шляхів. Наприклад, ви можете забути про Java на ПОС.

Вам належить увійти в режим складання мов асемблерної мови та писати процедурно.

Ви повинні тримати код порівняно рівним та уникати рекурсії, оскільки обмеження оперативної пам’яті часто можуть призвести до проблем із стеком.

Ви повинні навчитися писати ефективні процедури переривання обслуговування (як правило, мовою складання).

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

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

Це інший світ. Для мене наявність інформатики або професійного програмування може бути настільки ж перешкодою, як і відсутність знань взагалі при роботі з мікроконтролерами.


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

6
Все це вірно, крім відмови від орієнтації на об'єкт. Напевно, ви не будете використовувати мову з функціями OO, але це не виключає орієнтації на об'єкт. Для мікроконтролерів ви збираєтеся написати драйвери для всіх апаратних периферійних пристроїв (АЦП, контролери послідовних шин, ШІМ тощо, тощо). Такий драйвер завжди повинен бути записаний об'єктно-орієнтованим чином, щоб він був 1) автономним і не знав / не піклувався про решту програми, і 2) здійснював приватну інкапсуляцію, щоб решта програми не могла заходьте і спішаться з цим. Це на 100% можливо в C і не вплине на продуктивність.
Лундін

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

@Arsenal Note Я сказав "найбільше", і зауважте, що ви коментуєте чотирирічну тему. :)
Адам Лоуренс

Я повністю не згоден з першим і останнім реченням. А також збірка використовується досить рідко і, в основному, лише для 8-бітних MCU (просто перевірте на цьому форумі, скільки постів з асемблерним кодом ви можете знайти?). Ви, звичайно, можете і (ІМХО) повинні писати в стилі ОО для 32-бітних MCU
Андрейс Гасіловс

10

Вам потрібно продумати кілька речей:

  • Ви будете використовувати С як мову
  • Ви все ще можете створити відчуття орієнтації на об'єкт, використовуючи функціональні покажчики, щоб ви могли переосмислити функції тощо. Я використовував цей метод у минулих та поточних проектах і працює дуже добре. Таким чином, ОО частково є, але не в сенсі С ++.

Існують і інші обмеження, які будуть грати, такі як обмежена швидкість та пам'ять. Отже, як загальне керівництво, я уникаю:

  • Використовуючи купу, якщо є спосіб вирішити проблему без Маллока, я це роблю. Наприклад, я попередньо виділяю буфери і просто використовую їх.
  • Я навмисно зменшую розмір стека в налаштуваннях компілятора, щоб стикатися з проблемами розміру стека на початку, оптимізую це.
  • Я припускаю, що кожен рядок коду буде перерваний подією, тому я уникаю невідповідного коду
  • Я припускаю, що навіть переривання вкладені, тому я відповідно пишу цей код
  • Я уникаю використання ОС, якщо це не потрібно. 70% вбудованих проектів насправді не потребує ОС. Якщо я повинен використовувати ОС, я використовую лише те, що є вихідним кодом. (Freertos тощо)
  • якщо я використовую ОС, я майже завжди абстрагую речі, щоб я міг змінити ОС за лічені години.
  • Для драйверів і т. Д. Я буду використовувати лише бібліотеки, надані постачальником, я ніколи не прямую біти, якщо у мене немає іншого вибору. Це робить код читабельним і покращує налагодження.
  • Я переглядаю петлі та інші речі, особливо в ISR, щоб переконатися, що вони досить швидкі.
  • Я завжди тримаю під рукою кілька GPIO для вимірювання матеріалів, переключення контексту, часу виконання ISR тощо.

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


3
+1 для "Ви можете використовувати парадигми ОО, якщо хочете". Те, що вам потрібно перевірити у дверях, це не дизайн OO. OOD - це лише філософія, яка спонукає вас зберігати пов'язаний код та дані разом. Те, що вам потрібно залишити позаду, - це те, як OO реалізується в корпоративних системах, з безліччю шарів абстракції, інверсією контролю та всім цим джазом. Завдання вашої прошивки - керувати обладнанням, ось і все.
drxzcl

7

Я роблю і те, і інше, тому ось мій погляд.

Я думаю, що найважливіший навик на сьогоднішній день вбудований - це ваша здатність до налагодження. Необхідний спосіб мислення значно відрізняється тим, що набагато більше може піти не так, і ви повинні бути дуже відкритими до розгляду всіх різних способів, що ви намагаєтесь зробити, можуть піти не так.

Це найбільша проблема для нових вбудованих розробників. Люди на ПК, як правило, більш грубі, оскільки вони звикли так просто працювати на них. Вони, як правило, витрачають багато часу на пошуки інструментів, щоб зробити замість них речі (підказка: їх не так багато). Там багато стукає головами в стіни знову і знову, не знаючи, що ще робити. Якщо вам здається, що ви застрягли, відступіться і з’ясуйте, чи зможете ви визначити, що все може піти не так. Систематично проходьте звуження списку потенційних проблем, поки не з’ясуєте це. Безпосередньо з цього процесу випливає, що вам слід обмежити коло проблем, не змінюючи занадто сильно відразу.

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

Ви працюєте над кодом, який працює за зовнішньою системою до вашої системи розвитку, з різним ступенем видимості для вашої цілі від платформи до платформи. Якщо ви перебуваєте під вашим контролем, натисніть на розробку посібників, щоб допомогти збільшити цю видимість у вашій цільовій системі. Використовуйте послідовні порти налагодження, вивід налагодження біт-ударів, відомий миготливий індикатор тощо. Звичайно, як мінімум, навчіться користуватися осцилографом та використовувати штифтовий ввід / вивід із "областю", щоб побачити, коли певні функції входять / виходять, спрацьовують ІРС та ін. Я спостерігав, як люди борються буквально на роки довше, ніж це потрібно, просто тому, що вони ніколи не намагалися налаштувати / навчитися користуватися правильним посиланням налагодження JTAG.

Набагато важливіше бути дуже обізнаним, які саме ресурси у вас є щодо ПК. Уважно прочитайте таблиці. Поміркуйте, що ресурс "коштує" всього, що ви намагаєтесь зробити. Вивчіть налагодження налагодження, орієнтовані на ресурси, як наповнення простору стеку магічним значенням для відстеження використання стека.

Хоча деяка ступінь навичок налагодження потрібна як для ПК, так і для вбудованого програмного забезпечення, це набагато важливіше з вбудованим.


5

Я припускаю, що ваш C ++ досвід базується на ПК.

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

Залежно від платформи, над якою ви працюєте, вам доведеться мати справу з дуже низьким рівнем вводу / виводу . У деяких середовищах розробки є функції запису на РК-дисплей, але в інших ви самостійно, і вам доведеться зчитувати таблицю даних ЖК-дисплея від початку до кінця, щоб знати, як керувати ним.
Можливо, вам доведеться керувати реле, це простіше, ніж РК-дисплеєм, але це вимагатиме переходу на рівень регістра мікроконтролера. Знову таблицю даних чи посібник користувача. Вам потрібно буде ознайомитись зі структурою мікроконтролера, яку ви знайдете на блок-схемі, знову ж таки в таблиці. У часи мікропроцесора ми говорили про модель програмування, яка в основному була лінійкою регістрів процесора. Сьогоднішні мікроконтролери настільки складні, що опис усіх регістрів може містити найкращу частину аркуша на 100 сторінок. IIRC тільки опис годинникового модуля для MSP430 склав 25 сторінок.

мк

Мікроконтролери часто запрограмовані в C . C ++ - це скоріше голодні ресурси, тому зазвичай немає. (Більшість реалізацій C ++ для мікроконтролерів пропонують обмежений підмножина C ++.) Як я вже говорив, залежно від платформи у вас може бути наявна широка бібліотека функцій, яка може заощадити вам досить часу на розробку. Варто витратити трохи часу, щоб вивчити це, це може заощадити вам багато часу пізніше, якщо ви знаєте, що є в наявності.


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

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

Не зовсім 200 років. Він дебютував у 1977 році, так що не було навіть 30. Хоча я згоден, що це було еони тому в технологічному плані, я все одно здутий тим, що не тільки збільшення ста утримуваних, ні збільшення в тисячу разів , але збільшилася на мільйон разів оперативна пам'ять та розмір коду. Швидкість не настільки сильно зросла, оскільки 2600 був 1,19 МГц, а новіші системи лише в низькому діапазоні ГГц. Вони можуть зробити набагато більше за цикл, ніж 2600 (що могло - і довелося - генерувати 1/76 відео рядків кожного циклу), але я не думаю, що вони 1000 000x настільки швидкі.
supercat

3

"апаратне програмування" може означати багато речей. Програмування дуже невеликого чіпа (подумайте 10F200, 512 інструкцій, кілька байт оперативної пам’яті) може бути майже схожим на проектування електронної схеми. З іншого боку, програмування великого мікроконтролера Cortex (1 Мб FLASH, 64 кБ оперативної пам’яті) може бути дуже схожим на програмування ПК / GUI, використовуючи великий інструментарій GUI. IMHO хороший програміст із вбудованим / реальним часом потребує навичок як із програмного забезпечення, так і з боку проектування схеми. Для великих uC C ++ - це хороший вибір мови, для дуже маленьких C може бути єдиним вибором. Знання зі зборів можуть бути корисними, але я б не рекомендував робити серйозні проекти цілком у зборі.

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

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


1

Для кожного методу бібліотеки ардуїно, який ви називаєте, існує безліч код C / C ++, що дозволяє це просто упаковувати, щоб використовувати його як API. Погляньте на вихідний код ардуїно в апараті каталогу / arduino / *, і ви побачите всі написані для вас C / C ++, які взаємодіють безпосередньо з регістрами мікроконтролерів AVR. Якщо ваша мета полягає в тому, щоб навчитися писати подібні речі (безпосередньо для обладнання), то є багато чого. Якщо ваша мета полягає в тому, щоб змусити щось працювати, використовуючи їх бібліотеки, про це може не багато говорити, оскільки більшість важкої роботи робиться саме для вас, а їх бібліотеки та середовище розробки дуже прості у використанні.

Деякі правила, хоча при роботі з обмеженими ресурсами пристроями, які можуть застосовуватися до ардуїнового середовища або інших:

Будьте в курсі, скільки пам'яті ви використовуєте. Як розмір коду (який йде у флеш-пам'ять), так і статичне використання ОЗУ (константи у вашому коді, які завжди будуть існувати в ОЗУ). Я заперечую, що статичне використання оперативної пам’яті є дещо важливішим, оскільки її легко переглядати. Не рідкість у вас є лише 1000 байт, з якими можна працювати для вашої стеки, купи та констант. Будьте розумні в тому, як ви їх витрачаєте, тому уникайте таких речей, як довгі масиви цілих чисел (4 байти кожен), коли байтів або неподписаних знаків (1 байт кожен) буде достатньо. Інша відповідь тут дуже добре стосується деяких інших важливих моментів, тому я зупинюсь тут, я в основному хотів зрозуміти, що є багато, що можна висвітлити, якщо ви не використовуєте бібліотеку arduino і не пишете власні бібліотеки С.


0

Щодо програмування мікроконтролера та OOP, вони не є чимось протилежністю. Це правда, що всі бібліотеки постачальників знаходяться в простому C, але всі платформи також підтримують C ++ OOP. Крім того, розробники можуть створювати та створювати C ++ бібліотеки високого рівня та мікропрограмне забезпечення пристроїв. Хороший приклад - бібліотеки Arduino, офіційні та побудовані користувачем - в основному це класи C ++. Можливо, не всі переваги OOP можуть бути повністю використані у вбудованому середовищі, але добре відомі переваги C ++ і C є чинними і тут.

Щодо мислення та мислення, як зазначається в інших відповідях, мікроконтролери є дуже обмеженими ресурсами платформами (особливо в оперативній пам'яті, меншою швидкістю) - такі речі, як динамічне розподілення пам'яті, винятки C ++, як правило, виключаються. Враховуючи правильне обладнання, легко прийняти ці обмеження та використовувати інші методи (також широко використовувані на інших платформах).

На мій погляд, складнішим викликом може бути ще один додатковий вимір, який можна знайти у вбудованому програмуванні - синхронізація. Це тому, що зазвичай вбудоване програмне забезпечення багато справляється з подіями в режимі реального часу, строго приуроченими протоколами до керування периферійним обладнанням і загальним завданням (це також деякі паралелі в інших "високорівневих" платформах, як і багатопотокові програми).

Будьте готові прочитати багато таблиць даних при роботі з новим обладнанням - я думаю, це може бути пов’язано з питаннями "настрій мислення" :) Напевно, знадобляться деякі знання з технічного обслуговування та обладнання.

Також хочеться зазначити, що в наші дні для розробки вбудованого програмного забезпечення не потрібна мова складання. Насправді Java (BTW за замовчуванням це OOP) вже є і стає сильнішою (принаймні, для деяких класів вбудованих пристроїв, наприклад, пристроїв IoT, це може мати дуже світле майбутнє).


З точки зору занепокоєння, питання щодо динамічного (пере) розподілу пам'яті, як правило, є більшою перешкодою для традиційного ОО, ніж хронометраж .
Кріс Страттон

Можливо, ти маєш рацію. Але є люди, які програмували в 80-90-х роках для програмного забезпечення реального режиму MSDOS, маючи 64К (сегмент пам’яті даних) оперативного простору, і для них це було «природно». Можливо, MSDOS PC був більш "вбудованим" середовищем, ніж сьогодні STM32F4 :)
Flanker

STM32F4, як правило, має більше програмної пам’яті у вигляді спалаху, але ПК зазвичай має набагато більше оперативної пам’яті для зберігання змінних об'єктів виконання. Хоча вся далека вказівна річ, вимушена сегментованою адресацією, була болем, і обом не вистачає справжнього MMU, і це буде ще більше турбувати систему з меншою пам’яттю пам'яті, що є STM32F4. Також час роботи на ПК, як правило, був коротшим, а допустимі показники відмов вищі.
Кріс Страттон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.