ほとんど誰もが今祝福を言うでしょう:
パフォーマンス!
さて、[〜#〜] c [〜#〜]は運動コードを書くことができます。しかし、結局そうすることができる他の言語があります!そして、最新のコンパイラーの最適化能力は素晴らしいです。 [〜#〜] c [〜#〜]には、他の言語にはない利点がありますか?それとも、ドメイン内にもっと柔軟な機器が必要ないのでしょうか?
ほとんど誰もが今祝福を言うでしょう:
パフォーマンス!
それはその一部です。最初はリソースが限られているデバイスでは、確定的なリソースの使用が重要ですが、他の理由もあります。
Cは、アセンブリ言語を記述するだけでなく、プラットフォーム間でUnixを移植可能にするために作成されたため、CPUをモデル化するように設計されました。
つまり、Cプログラムは、実際のCPUに非常に近い抽象化レベルを必要とするプログラムのプログラミング言語としてうまく機能します。これは、組み込みハードウェアの場合です。
注:Cは1970年頃に設計されたもので、CPUの方が単純でした。
支配の理由の1つは、タスクに適切な種類のツールがあることです。 JavaとC/C++の両方で組み込みプラットフォームで開発した後、C++の基本的なアプローチはより自然であると言えるでしょう。言語が高すぎるためにフープを飛び越えているのは非常に迷惑なことです。1つの良い例は、Javaに符号なし変数がないことです。
また、VM /解釈済み言語の便利な機能は通常実現不可能であり、実装から除外されています。ガベージコレクション。
C自体は実行時サポートをほとんど必要としないため、オーバーヘッドははるかに低くなります。ランタイムサポートにメモリやストレージを費やしたり、そのサポートを最小限に抑えるために時間や労力を費やしたり、プロジェクトの設計でそれを考慮に入れたりする必要はありません。
他の回答で述べたように、Cは1970年代初頭にミニコンピューターアーキテクチャーのアセンブリー言語を置き換えるために開発されました。当時、これらのコンピュータのコストは通常、メモリや周辺機器を含めて数万ドルです。
現在、16ビットの組み込みマイクロコントローラーを使用すると、組み込みのRAMおよびI/Oコントローラーを含めて、単一の数量で4ドル以下のコストで同じかそれ以上のコンピューター能力を得ることができます。A 32ビットマイクロコントローラーのコストは、おそらく1〜2ドルです。
私がこれらの小さな人をプログラミングしているとき、それが私が彼らが座るボードを設計していないときの90%の時間ですが、プロセッサーが何をしているかを視覚化したいです。アセンブラで十分に速くプログラミングできれば、そうするでしょう。
あらゆる種類の抽象化レイヤーが欲しいわけではありません。画面上の逆アセンブラーのリストをステップスルーしてデバッグすることがよくあります。そもそもCでプログラムを記述した方が、はるかに簡単です。
コンパイラが改善され、ハードウェアのパフォーマンスが向上したため、C++がますます使用されるようになるため、完全には支配されません。ただし、Cはいくつかの理由で依然として非常に人気があります。
幅広いサポート。ほとんどすべてのチップベンダーがcコンパイラを提供しており、サンプルコードとドライバはすべてcで作成されます。 C++コンパイラはますます一般的になってきていますが、特定のチップの有効な証明書ではなく、バグが多いことがよくあります。また、埋め込まれたエンジニアなら誰でもcで作業できることも知っています。それは業界の共通語です。
パフォーマンス。うん、あなたはそれを言った。パフォーマンスは依然として重要であり、コアルーチンがまだアセンブラーで頻繁に記述されている環境、または少なくともアセンブリ出力を参照してcで最適化されている環境では、これの重要性を過小評価しないでください。多くの場合、埋め込まれたターゲットは非常に低コストで、メモリが非常に少なく、ミップがほとんどありません。
サイズ。 C++は大きくなる傾向があります。確かに、STLを使用するものはすべて大きくなります。一般に、プログラムサイズとメモリフットプリントの両方の点で。
保守主義。それは非常に保守的な業界です。失敗のコストが高く、デバッグにアクセスしにくいことが多いため、変更する必要がないためもあります。小さな組み込みプロジェクトの場合、cはうまく機能します。
組み込みソフトウェアは非常に異なります。
デスクトップアプリでは、抽象化とライブラリによって開発時間を大幅に節約できます。問題が発生すると、別の数メガバイトまたはギガバイトのRAMまたは2 + GHz 64ビットCPUコア)を投げる余裕があり、他の誰か(ユーザー)がそのハードウェアの代金を払っています。アプリが実行されるシステムがわからない。
組み込みプロジェクトでは、リソースが非常に制限されることがよくあります。私が取り組んだ1つのプロジェクト(PIC 17Xシリーズプロセッサ)では、ハードウェアに2Kワードのプログラムメモリ、8レベルの(ハードウェア内)スタック、および192バイト(<0.2kB)のRAMがありました。異なるI/Oピンには異なる機能があり、ハードウェアレジスタに書き込むことによって、必要に応じてハードウェアを構成しました。デバッグには、オシロスコープとロジックアナライザーが含まれます。
組み込みでは、抽象化が邪魔になり、所有していないリソースを管理(およびコスト)することがよくあります。例えば。ほとんどの組み込みシステムにはファイルシステムがありません。電子レンジは組み込みシステムです。車のエンジンコントローラー。いくつかの電動歯ブラシ。一部のノイズキャンセリングヘッドフォン。
組み込みシステムを開発する上で私にとって非常に重要な要素の1つは、コードが命令、リソース、メモリ、実行時間の観点からどのように変換されるかを知り、制御することです。多くの場合、命令の正確なシーケンスは、ハードウェアインターフェイス波形のタイミング。
抽象化と舞台裏の「マジック」(ガベージコレクターなど)は、デスクトップアプリに最適です。ガベージコレクターは、メモリを動的に割り当てることができる場合、メモリリークを追跡する時間を大幅に節約します。
ただし、リアルタイムの組み込みの世界では、物事の所要時間を知り、時にはナノ秒まで制御する必要があり、問題が発生したときに別の数メガRAMまたはより高速なCPU)をスローすることはできません。1つの簡単な例:デューティサイクルを制御してLEDのソフトウェア調光を行う場合(CPUはLEDのオン/オフ制御のみを持っていました)、プロセッサがオフになり、たとえば100msのガベージコレクションを実行することはできません。明らかに明るく点滅するか、外に出ます。
より仮説的な例は、点火プラグを直接点火するエンジンコントローラです。そのCPUがオフになり、50ミリ秒間ガベージコレクションを実行すると、エンジンが一瞬停止するか、間違ったクランクシャフト位置で発火し、エンジンが停止するか(通過中に?)、機械的に損傷する可能性があります。あなたは誰かを殺されるかもしれません。
組み込みシステムの場合、重要なのはパフォーマンスです。しかし、あなたが言ったように、なぜ他のパフォーマンス言語ではなくCなのか?
これまで多くの人がコンパイラの可用性について言及しましたが、誰も開発者の可用性について言及していません。たとえばOCamlよりもはるかに多くの開発者がすでにCを知っています。
それらは3つの重要な要素です。