Це скоріше думка / коментар, ніж відповідь.
Ви не хочете і не повинні програмувати на C. C ++, якщо правильно користуватися , набагато перевершує. (Гаразд, я мушу визнати, що при неправильному використанні це набагато гірше, ніж C.) Це обмежує вас чіпами, які мають (сучасний) компілятор C ++, що є майже всім, що підтримується GCC, включаючи AVR (з деякі обмеження, філо згадує проблеми нерівномірного адресного простору), але виключаючи майже всі ПІК (PIC32 може бути підтриманий, але я ще не бачив пристойного порту).
Коли ви програмуєте алгоритми на C / C ++, різниця між варіантами, про які ви згадуєте, невелика (за винятком того, що 8 або 16 бітовий мікросхема буде дуже серйозним недоліком, коли ви робите велику арифметику біт 16, 32 або вище). Коли вам потрібна остання унція продуктивності, вам, ймовірно, потрібно буде використовувати ассемблер (власний або код, наданий постачальником або третьою стороною). У такому випадку ви можете повторно розглянути обраний вами чіп.
Коли ви кодуєте обладнання, ви можете або використовувати якийсь шар абстракції (часто надається виробником) або написати свій власний (на основі коду даних та / або прикладу коду). ІМЕ існуючих абстракцій C (mbed, cmsis, ...) часто функціонально (майже) коректні, але жахливо спрацьовують (перевіряйте, що старі деталі займають близько 6 шарів непрямості для операції встановлення штифтів), зручність використання та портативність. Вони хочуть розкрити для вас всю функціональність певного чіпа, що майже у всіх випадках вам не знадобиться, і, швидше за все, не піклується, і він блокує ваш код саме до цього постачальника (і, можливо, саме цього чіпа).
Це було, якщо C ++ може зробити набагато краще: при правильному виконанні набір контактів може пройти через 6 або більше шарів абстракції (адже це робить кращий (портативний!) Інтерфейс і можливий коротший код), але при цьому надавати інтерфейс, не залежний від цілі для простих випадків , і все одно призводить до того ж машинного коду, який ви писали в асемблері .
Фрагмент стилю кодування, який я використовую, може або зробити вас ентузіастичним, або відвернутись від жаху:
// GPIO part of a HAL for atsam3xa
enum class _port { a = 0x400E0E00U, . . . };
template< _port P, uint32_t pin >
struct _pin_in_out_base : _pin_in_out_root {
static void direction_set_direct( pin_direction d ){
( ( d == pin_direction::input )
? ((Pio*)P)->PIO_ODR : ((Pio*)P)->PIO_OER ) = ( 0x1U << pin );
}
static void set_direct( bool v ){
( v ? ((Pio*)P)->PIO_SODR : ((Pio*)P)->PIO_CODR ) = ( 0x1U << pin );
}
};
// a general GPIO needs some boilerplate functionality
template< _port P, uint32_t pin >
using _pin_in_out = _box_creator< _pin_in_out_base< P, pin > >;
// an Arduino Due has an on-board led, and (suppose) it is active low
using _led = _pin_in_out< _port::b, 27 >;
using led = invert< pin_out< _led > >;
Насправді є ще кілька шарів абстракції. І все ж остаточне використання світлодіоди, скажімо, для його включення не показує складності або деталей цілі (для ардуїнової уно або синьої таблетки ST32 код буде ідентичним).
target::led::init();
target::led::set( 1 );
Компілятор не залякує всі ці шари, і оскільки немає віртуальних функцій, оптимізатор бачить все (деякі деталі, опущені, як включення периферійних годин):
mov.w r2, #134217728 ; 0x8000000
ldr r3, [pc, #24]
str r2, [r3, #16]
str r2, [r3, #48]
Ось як я написав би це в асемблері - якби я зрозумів, що регістри PIO можна використовувати з компенсаціями із загальної бази. У цьому випадку я, мабуть, хотів би, але компілятор набагато краще оптимізує такі речі, ніж я.
Тож, наскільки я маю відповідь, це так: напишіть шар абстракції для вашого обладнання, але робіть це в сучасних C ++ (концепціях, шаблонах), щоб це не зашкодило вашій роботі. З цим на місці ви можете легко перейти на інший чіп. Ви навіть можете почати розробку на якійсь випадковій мікросхемі, з якою у вас є прокладка, знайомі з нею, мати гарні інструменти для налагодження тощо і відкласти остаточний вибір на пізніше (коли у вас буде більше інформації про необхідну пам'ять, швидкість процесора тощо).
IMO, одна з хибностей вбудованої розробки, - це спочатку вибрати чіп (це питання, яке часто задають на цьому форумі: який чіп я повинен обрати .... Найкраща відповідь, як правило, не має значення.)
(редагувати - відповідь на "Отже, ефективність роботи, C або C ++ була б на одному рівні?")
Для одних і тих же конструкцій C і C ++ однакові. C ++ має набагато більше конструкцій для абстрагування (лише декілька: класи, шаблони, конспектор), які можна, як і будь-який інструмент, використовувати для добра або для поганого. Щоб зробити дискусії цікавішими: не всі згодні з тим, що добре чи погано ...