これは答えというよりも意見/コメントです。
Cでのプログラミングは望ましくなく、またすべきではありません。C++ は、正しい方法で使用するとはるかに優れています。(OK、間違った使い方をすると、Cよりもはるかに悪いことを認めざるを得ません。)これにより、(最新の)C ++コンパイラを搭載したチップに制限されます。これは、AVRを含むGCCでサポートされているほぼすべてのものです(いくつかの制限、filoは不均一なアドレス空間の問題について言及していますが、ほとんどすべてのPICを除外しています(PIC32はサポートされている可能性がありますが、適切なポートはまだ見ていません)。
C / C ++でアルゴリズムをプログラミングしている場合、言及する選択肢の違いはわずかです(ただし、16ビット、32ビット、またはそれ以上のビット演算を大量に実行する場合、8ビットまたは16ビットのチップは深刻な欠点になります)。最後の1オンスのパフォーマンスが必要な場合は、おそらくアセンブラ(独自のコード、またはベンダーまたはサードパーティが提供するコード)を使用する必要があります。その場合は、選択したチップを再検討する必要があります。
ハードウェアにコーディングするときは、抽象化レイヤーを使用するか(多くの場合、製造元から提供されます)、独自に作成することもできます(データシートやコード例に基づいて)。IMEの既存の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 > >;
実際には、抽象化の層がさらにいくつかあります。しかし、LEDを最後に使用すると、たとえばオンにしても、ターゲットの複雑さや詳細は表示されません(Arduin unoまたは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 ++(概念、テンプレート)でそれを書くことです。それを配置すると、別のチップに簡単に切り替えることができます。配置しているランダムチップで開発を開始したり、使い慣れたり、適切なデバッグツールを使用したりして、最終的な選択を後で延期することもできます(必要なメモリ、CPU速度などの詳細情報がある場合)。
IMO組み込み開発のファラシーの1つは、最初にチップを選択することです(これは、このフォーラムでよく尋ねられる質問です。どのチップを選択すればよいですか。一般に、最良の答えは、問題ではありません)。
(編集-「パフォーマンスに関して、CまたはC ++は同じレベルになるでしょうか?」への応答)
同じ構成の場合、CとC ++は同じです。C ++には、他の抽象化用の構成要素(クラス、テンプレート、constexprがいくつかあります)があり、他のツールと同様に、良いものにも悪いものにも使用できます。ディスカッションをより面白くするために、誰もが良い点と悪い点に同意するわけではありません...