質問

関連:

マイクロコントローラーのコードを書いている場合あなたがアセンブリまたはCまたは他の高水準言語で書く場合の本当の違いは? Cコードを書いた場合、どのようにコンパイルしますか?

ありがとう

役に立ちましたか?

解決

いくつかのコメント:

1)パフォーマンスまたは最適化の制約が正当化しない限り、絶対にアセンブリをしない。次のメトリックは、アセンブリを使用して屋根を通過します。

  • コーディングの時間
  • デバッグの時間
  • テストの時間
  • 文書化する時間
  • コードを作成したときに何をしていたかを把握する時間(1年後)
  • 間違いを犯す可能性

2)名前空間カプセル化<!> ampの場合、私の好みはCではなくC ++です。 コンパイル時オブジェクト指向の実践の促進。 Cには、グローバル変数と名前空間の衝突の機会が多すぎます。 (リアルタイムJavaは素晴らしいと思いますが、私が理解していることから、その要件はまだかなり高いです)

またはC ++のサブセット:例外、仮想関数、実行時の型識別、ほとんどの場合動的メモリ割り当ても除外します-通常、多くの追加リソースを必要とするため、コンパイル時に未指定のままになっているものランタイム中。それが<!> quot; bloat <!> quot; C ++の。

私はT ++およびIARのC ++コンパイラ、TMS320およびMSP430マイクロコントローラー(それぞれ)を使用し、適切な最適化設定を使用して、C ++から予想されるオーバーヘッドを削減する素晴らしい仕事をしています。 (特にinlineキーワードを賢明に使用して支援する場合)

優れたコードの再利用を促進するコンパイル時の利点のいくつかにテンプレートを使用しました。 8ビット、16ビット、および32ビットのCRCを処理する単一のソースコードファイルを作成します。およびコンパイル時ポリモーフィズムにより、クラスの通常の動作を指定し、それを再利用できますただし、その機能の一部をオーバーライドします。繰り返しますが、適切な最適化設定により、TIコンパイラのオーバーヘッドは非常に低くなりました。

Microchip PIC用のC ++コンパイラを探しています。私が見つけた唯一の会社はIARです。 ($$$は障害でしたが、いつかコピーを購入したいと思います)Microchip C18 / C30コンパイラはかなり良いですが、C ++ではなくCです。

3)コンパイラの最適化に関する特定の警告:デバッグを非常に困難にする可能性があります。多くの場合、最適化されたC / C ++コードをシングルステップで実行することは不可能であり、ウォッチウィンドウには、最適化されていないコードに含めるべきとは相関しない変数が表示される場合があります。 (優れたデバッガーは、特定の変数が存在しないか、メモリー位置ではなくレジスターに最適化されていることを警告します。多くのデバッガーはそうではありません。<!> gt; :(

また、優れたコンパイラーでは、#pragmasを使用して関数レベルで最適化を選択または選択できます。使用したものでは、ファイルレベルでの最適化のみを指定できます。

4)Cコードとアセンブリのインターフェイス:これは通常困難です。最も簡単な方法は、必要な署名を持つスタブ関数を作成することです。 uint16_t foo(uint16_t a, uint32_t b) {return 0; }、ここでuint16_t = unsigned short、通常ビット数を明示的にします。次に、それをコンパイルして、生成するアセンブリを編集し(コードの開始/終了部分だけを残してください)、完了後にレジスタを復元せずにレジスタを上書きしないように注意します。

割り込みの有効化/無効化のような非常に簡単な非常にを行わない限り、通常、インラインアセンブリに問題が発生する可能性があります。

私が一番好きなアプローチはコンパイラ組み込み関数です/ <!> quot; extended ASM <!> quot;構文。 MicrochipのCコンパイラはGNU Cコンパイラに基づいており、<!> quot; extended ASM <!> quot;これにより、インラインアセンブリのビットをコーディングできますが、参照しているレジスタ/変数を通知するための多くのヒントを与えることができ、アセンブリコード<!> quot; pを確認するために、レジスタのすべての保存/復元を処理します素敵な<!> quot; C. TIのTMS320 DSP用コンパイラはこれらをサポートしていません。いくつかの用途がある組み込み関数の限られたセットがあります。

アセンブリを使用して、頻繁に実行される制御ループコードを最適化するか、sin()、cos()、およびarctan()を計算しました。しかし、そうでなければアセンブリから離れて、高級言語を使い続けるでしょう。

他のヒント

ほとんどのマイクロコントローラーメーカーは、PCでコードをコンパイルしてからマイクロコントローラーに転送できるクロスコンパイラーを提供しています。

なぜCなのか
Cの利点は、将来、コードを他のマイクロコントローラーに移植しやすくなることです。コンピューティングの歴史から、コードは通常ハードウェア実装よりも長持ちすることが示されています。
2番目の利点は、コードをより読みやすく保守しやすくする制御構造(もしあれば)です。

アセンブリ言語の理由
手作業で最適化を行うことができます。

判定
この種の質問ではよくあることですが、トレードオフは特定の用途に大きく依存します。
多くの場合、Cコード内でアセンブリ呼び出しを行うことで2つを混在させることができるため、プロジェクトに適したバランスを見つけることができます。

PICハードウェアに固有
ほとんどのPICハードウェアにはGCCのオプションがないようです。一方、コメンターが指摘したように、16ビットPIC24およびdsPIC33用のMicrochip C30コンパイラはgccです。
PICは、 SDCC でもまだサポートされていません。
新しい情報:コメントによると、SDCCにはPICの実用的なサポートがあります。
他にもいくつかのオープンソースオプションがありますが、私はそれらの経験がありません。

最良の選択肢はおそらくCでコーディングすることです。その後、手作業で最適化する必要があり、コンパイラよりも優れたジョブを実行できる場合は、アセンブリをCファイルにコーディングする必要があります。

アセンブリコーディングはPCにとって過去のものですが、組み込みには非常に関連性があります。

埋め込みでのアセンブリの記述は、PCでのアセンブリの記述とは異なります。 PCコンパイラは<!> quot;人間よりも優れています<!> quot;最適化された命令の生成。組み込みシステムはしばしば奇妙なアーキテクチャを備えており、最適化コンパイラはPC最適化コンパイラほど成熟していません。

マイクロコントローラのアセンブリを書く際に遭遇した問題の1つは、コードがどのようにレイアウトされているかに非常に注意する必要があることです。メモリ境界を越えるジャンプテーブルを使用し、コードを実際に奇妙な場所にジャンプさせることは、かなり気がかりです。 Cでコーディングすると、コンパイラがそのベースをカバーします。

私は間違いなくCを使用します。より高速で、より信頼性の高いソフトウェアを作成します。アセンブリには、提供する機会がほとんどなく、まれにしかありません。 C:

では
  • PCからでも、既存のプラットフォームからコードを簡単に移植できます。
  • 実行速度やコードサイズを犠牲にすることなく、高水準言語で開発できます。高品質のコンパイラが利用できる場合(PIC18には多くの選択肢があります)、Cの方が手作りのアセンブリよりも優れているでしょう。
  • コードのデバッグ、テスト、および保守がはるかに簡単です。 Cはより信頼性の高いコードを生成します。

特にPIC18に関係するもう1つのこと。直感的ではないPICアーキテクチャやメモリバンクなどに対処する必要はありません。

過去に8051向けの IAR Cコンパイラを使用した経験があります。

私の最近のアプローチは常にこれです:-

適切な最適化コンパイラを使用してCで記述し、サイズまたは速度に問題がある場合にのみ、アセンブラで特定の部分を書き換えることを検討してください。

ただし、このアプローチを取っているので、アセンブラーを1行だけ記述するのは必要ではありません...

Go for c!

私は大手CEメーカーで働いてきました。アセンブリを最後に見たのは、1996年頃、RC5およびRC6のデコードとTVチューニングアルゴリズム用の小さな割り込みサービスルーチンがいくつかあったことでした。 その後、常にcとC ++を使用しました(クラスのみを使用し、stl、例外、またはrttiは使用しませんでした)。 8051用の古いKEILコンパイラーとgreenhillsコンパイラー(MIPS)およびVxWorksツールセット(PowerPCベース)で良い経験があります。

Roddyが言うように、最初にCで記述し、後で必要に応じてアセンブリで最適化します。

アセンブリは多くの場合、高速化できます。デスクトップを使用している場合、コンパイラーは、手作業によるアセンブリが必要になることはめったにないように最適化される傾向がありますが、uCの世界では頻繁に必要になります。また、割り込み処理ルーチンなどを作成する必要がある場合は、Cで実行できないことがよくあります。

コンパイルについては、ターゲット用のCコンパイラを探し回ってください。

間違いなくC、ただし

  • プログラムのメモリは非常に限られています。アセンブラコードを手作業で最適化して苦労した後、この1024バイトのフラッシュにプログラムを収めることができます。残りのバイト数は0バイトです。この場合、Cコンパイラは役に立ちません。

  • 絶対的なタイミング制御が必要です。割り込みレイテンシが長すぎる場合は、アセンブラに依存する必要があります。

最近の問題は、6ピンと数バイトのRAMを備えたATTinyから、一部の人々のデスクトップコンピューターに恥をかかせる組み込みOSを実行するマルチコアSBCに至るまで、組み込みが可能なことです。

そのため、言語/開発環境の選択では、どれだけ効率的であるか、システムがどれほど複雑かを考慮する必要があります。

最初に-Cはどこでも機能し、非常にうまくスケールします。複雑に対処するために、外部ライブラリなどを呼び出すことになります。

非常に小さいマイクロ(バイト単位のフラッシュ/ RAMを測定する)の場合、ASMを使用するのが最善です。kbの範囲に達すると、カウントする必要がないため、Cまたはその他の従来の言語を使用できます。すべてのバイト。メガバイトでプレイできるようになったら、RTOSを使用してすべてを処理し、開発時間を短縮する能力と、おそらくその要件の両方が得られます。ハードウェアを手に入れたら、本格的なOSを実行できます。おそらく、ハードウェアから自分自身を抽象化して、Javaなどのパッド付きセルにすべてを書き込むことができます。もう本当のプログラマーではありません...;)

上記の例外は、ハードウェアから引き出すことができるすべてのパフォーマンスが必要な場合です。この時点で、効率を維持するためにレベルを1つまたは2つ下げる必要があります。

これは、後で最適化できるCを使用する場合の一番下の行です。Cまたはアセンブラー以外(C ++などは使用しません)を使用しません。

PICを使用している場合、またはアセンブラーのみを使用する8051を使用している場合、キーはマイクロコントローラーの命令セットです。 arm、avr、msp430のようなコンパイラー対応のisaである場合、Cを使用して入力を節約しますが、さまざまな理由でアセンブラーにいくつかのルーチンが存在する可能性があります。同様に、おそらくCライブラリを避けたいと思うでしょう。newlibでさえかさばりすぎて、コードやアイデアを借りることができますが、リンクするだけではいけません。ああ、質問に戻って、ターゲットで利用可能なCコンパイラをもう一度見てくださいarmとavrに問題はありません。おそらくmspも大丈夫です。 KeilやIarがコンパイラを販売するからといって、それを購入したり使用したりする必要があるわけではないので、有料のコンパイラと無料のコンパイラの出力は恐ろしい場合があります。とにかくasmに精通し、出力を調べる必要があります(これを行うにはおそらく逆アセンブラーを作成する必要があります)。

一番下の行(別の一番下の行)、グローバルな回答はありません(Cがグローバルな回答である以上のものは避けてください)、常にプラットフォームが何であるか、リソースが何であるか、タスクが何であるか、パフォーマンス要件が何であるかによって異なります移植性の要件は(もしそれがマイクロコントローラーに本当に埋め込まれている場合、その多くは定義上ポータブルではありません)どんなコンパイラー、デバッガー、jtagなどが利用できるかです。 。

アセンブリへの書き込みが必要になる場合がもう1つあります。低レベルのRAMテストなどを行う必要がある場合、データの保存場所を完全に制御する必要があります。

たとえば、 SIL -2(安全性整合性レベル)以上を確認するソフトウェア考えられるデータ破損を検出するために、RAMの継続的なチェックが必要になる場合があります。チェックするRAMの領域はチェック中は変更できないため、アセンブラーでテストを記述すると、たとえば特定のレジスターまたはRAMの別の領域にローカル変数を保存することで、これが正しいことを確認できます。 Cでは、不可能ではないにしても、これは難しいでしょう。

RAMをゼロにし、ゼロ以外の静的変数を初期化するスタートアップコードも、同じ種類のコードに対してアセンブラーで記述できますが、通常この種のコードが提供されます。

デバイス固有のペリフェラルに大きく依存するコードを記述しており、使用しているツールチェーンがそれらを効率的に使用するために必要な組み込み関数を提供していない場合(くだらないFreescale DSP563CCコンパイラなど)、アセンブリを使用します。

それ以外に、アセンブリと高レベル言語を使用する記述されていないルールは、デスクトップソフトウェア開発のルールとほぼ同じだと思います。コードをクリーンに保ち、保守しやすく、機械語でホットコードを最適化します。

アセンブラー言語のコードはフットプリントが小さく非常に高速ですが、アセンブラー言語で記述されたコードは再利用可能なコードではありません。このコードの再利用機能は、ソフトウェア設計の最も重要な機能です。たとえば、x86プロセッサ用のアセンブラプロジェクトコードがある場合、x86プロセッサのみで使用でき、ARMプロセッサでは使用できません。 ただし、x86プロセッサ用のプロジェクトC / C ++コードがある場合、ARMプロセッサ用にこのコードを使用できます。そのため、ソフトウェア開発のためにアセンブラーを使用しないことをお勧めします。

これまでのところ、ForthやSchemeについて誰も言及していないのは残念です。どちらも小規模な環境に適している可能性があり、生産性を大幅に向上させることができます。

プレーンCまたはパスカル、Modula2。ただし、コンパイラの可用性により、Cを意味します。

通常、動的な割り当てとプログラムのサイズは非常に限られているため、C ++などの追加機能はスタイルの面で興味深いものです。

また、アプリがタイトになった場合、より複雑なランタイムは苦痛になります。

アセンブラーも便利ですが、非常に大量に販売している場合に限り、ファームウェアが小さいほど、チップは小さくて安価(フラッシュが少なく)で、プログラムのサイズは監視可能です(参照:入手できる可能性があります)バグのない時間)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top