マイクロコントローラープログラミングとオブジェクト指向プログラミング


11

C ++でいくつかの基本的なオブジェクト指向プログラミング(Bツリー、ハッシュアルゴリズム、二重リンクリストの作成)を行い、Cで小規模なプロジェクト(関数電卓の作成など)を行いました。

ハードウェアプログラミング(特にマイクロコントローラー用)とソフトウェア/オブジェクト指向プログラミングは、プログラマーが持つ必要のある考え方や「考え方」の点でどの程度違いますか?

私のほとんどの人は通常、他の人よりも難しいと考えられていますか?

(上記のように)私のバックグラウンドでは、ハードウェアプログラミングに入る前に多くの準備が必要ですか、それともあまり準備をせずにすぐに飛び込むことができますか?


4
最大の学習曲線は、マイクロ内の特定のハードウェアをどのように駆動するかです。これには、何時間もデータシートを熟読することが含まれます。残念ながら、簡単な方法はありません。
drxzcl 2011

@rrazd、私はあなたがarduinoタグを含めたことに気づきました。これは、arduinoの配線言語とライブラリを使用するためですか?または、組み込みアプリケーションを純粋なCで作成しますか?arduino環境を使い続けるつもりなら、ハードウェアからいくつかの抽象化を行っているので、かなり安全で簡単に遊ぶことができます。
Jon L

@Jon私は最初にarduinoボードを使用する予定です。C言語に似ていませんか?私は....それは同じ基本的な概念を関与思った
rrazd

1
多くの人が「I / Oプログラミング」と呼ぶものを意味するのか、それともコードを使用してハードウェアを再配置することを予期しているのかと思います。arduinoは明らかに前者です。後者はFPGAのドメインです。
JustJeff 2011

1
@rrazd-タイトルを変更しました。「ハードウェアプログラミング」は、FPGAやCPLDのプログラミングに使用されるVHDLやVerilogなどのHDL(ハードウェア記述言語)に非常に似ています。
stevenvh

回答:


10

ほとんどのマイクロコントローラーを扱う場合、オブジェクト指向のパラダイムを完全に放棄する必要があります。

マイクロコントローラーは通常、レジスターとRAMに制限があり、クロックレートが遅く、パイプライン処理/並列コードパスがありません。たとえば、PICでJavaを忘れることができます。

アセンブリ言語の考え方に入り、手続き的に書く必要があります。

RAMの制限によりスタックの問題が発生することが多いため、コードを比較的フラットに保ち、再帰を回避する必要があります。

効率的な(通常はアセンブリ言語で)割り込みサービスルーチンを作成する方法を学ぶ必要があります。

コンパイラがサポートしていない(またはサポートが不十分な)機能を実装するには、コードの一部をアセンブリ言語で手動でリファクタリングする必要がある場合があります。

ほとんどのマイクロコントローラーのワードサイズとFPU機能の欠如を考慮した数学コード(つまり、8ビットのmicro = evilで32ビットの乗算を行う)を記述する必要があります。

それは別の世界です。私にとって、コンピューターサイエンスや専門的なプログラミングのバックグラウンドを持つことは、マイクロコントローラーを扱うときにまったく知識がないのと同じくらい大きな障害になる可能性があります。


1
オブジェクト指向のパラダイムを完全に放棄する必要はありませんが、小さなマイクロでは、重いオブジェクトの実装を放棄し、各問題を解決するための最良の方法を本当に考える必要があるかもしれません。多くの場合、それは手続き型ですが、(通常は手動で)適切に実装された軽量オブジェクトは、複雑なマイクロコントローラープロジェクトのサイズを縮小することがあります。
Chris Stratton

6
オブジェクト指向を放棄することを除いて、これはすべて真実です。OO機能を備えた言語はおそらく使用しませんが、オブジェクト指向を除外するわけではありません。マイクロコントローラーの場合は、すべてのハードウェア周辺機器(ADC、シリアルバスコントローラー、PWMなど)のドライバーを作成します。そのようなドライバーは常に1)自律的であり、プログラムの残りの部分を認識しない/気にしない、および2)プログラムの残りの部分ができないようにプライベートカプセル化を実装するように、常にオブジェクト指向の方法で作成する必要があります。中に入ってそれをいじる。これはCでは100%可能であり、パフォーマンスには影響しません。
ランディン、2011年

1
最初の文に強く同意しません。すべてのマイクロコントローラープロジェクトはC ++とオブジェクト指向のアプローチで構築されており、使用したマイクロはそれほど大きくありません(32kBのROM)。オブジェクト指向のブートローダーも2kB未満でした。実際には制限はありません。クレイジーなことはできませんが、デザインはオブジェクト指向で問題ありません。
アーセナル

@アーセナルノート私は「ほとんど」と言っており、4歳のスレッドについてコメントしていることに注意してください。:)
Adam Lawrence

私は最初と最後の文に完全に同意しません。また、アセンブリはめったに使用されず、ほとんどが8ビットMCUにのみ使用されます(このフォーラムを確認してください。アセンブリコードを含む投稿はいくつありますか?)。32ビットMCUの場合、OOスタイルで書けるはずです(
IMHO)

10

あなたはいくつかのことを考える必要があります:

  • 言語としてCを使用します
  • 関数ポインターを使用してオブジェクト指向の感覚を作成できるため、関数などをオーバーライドできます。私は、過去および現在のプロジェクトでこのメソッドを使用しており、非常にうまく機能しています。したがって、OOは部分的に存在しますが、C ++の意味ではありません。

制限された速度やメモリなど、他にもプレイに伴う制限があります。したがって、一般的なガイドラインとして、私は避けます:

  • ヒープを使用して、Mallocなしで問題を解決する方法がある場合は、それを行います。たとえば、バッファを事前に割り当てて使用します。
  • コンパイラ設定でスタックサイズを意図的に減らして、スタックサイズの問題に早期に直面し、慎重に最適化します。
  • コードのすべての1行がイベントによって中断されることを想定しているので、再入不可能なコードは避けます
  • 割り込みもネストされていると思いますので、それに応じてそのコードを記述します
  • 必要なとき以外はOSを使わない。組み込みプロジェクトの70%は本当にOSを必要としません。OSを使用する必要がある場合は、ソースコードが利用可能なもののみを使用します。(フリートスなど)
  • OSを使用している場合は、ほとんど常に抽象化しているため、OSを数時間で変更できます。
  • ドライバーなどについては、ベンダーが提供するライブラリーのみを使用します。他に方法がない限り、ビットを直接いじることはありません。これにより、コードが読みやすくなり、デバッグが改善されます。
  • ループやその他のもの、特にISRを調べて、十分に高速であることを確認します。
  • 私は常に、いくつかのGPIOを手元に置いて、もの、コンテキスト切り替え、ISRランタイムなどを測定します。

リストは続きますが、ソフトウェアプログラミングに関してはおそらく平均を下回っています。もっと良い方法があるはずです。


3
「必要に応じてOOパラダイムを使用できます」の+1。ドアで確認する必要があるのはOOデザインではありません。OODは、関連するコードとデータを一緒に保つことを奨励する哲学にすぎません。あとに残しておく必要があるのは、OOがエンタープライズシステムに実装される方法であり、複数の抽象化レイヤー、制御の反転、すべてのジャズを備えています。ファームウェアのタスクは、ハードウェアを駆動することです。それだけです。
drxzcl 2011

7

私は両方を行うので、これが私の見解です。

組み込みで最も重要なスキルはデバッグ能力です。必要な考え方は大きく異なり、多くの場合は失敗する可能性があります。また、自分がやろうとしていることのすべてが異なる方法で失敗する可能性があることを考慮することに、非常に率直でなければなりません。

これは、新しい組み込み開発者にとって単一の最大の問題です。PCの人々は、彼らのために働くことに慣れているので、それをより荒くする傾向があります。彼らは代わりに何かをするためのツールを探すのに多くの時間を浪費する傾向があります(ヒント:多くはありません)。他に何をすべきかわからないまま、頭を何度も壁にぶつけています。行き詰まっていると感じた場合は、一歩下がって、すべての問題の原因を特定できるかどうかを判断してください。あなたがそれを理解するまで、体系的にあなたの潜在的な問題のリストを絞り込みます。このプロセスの直後から、一度にあまり変更しないことで問題の範囲を制限する必要があります。

経験豊富な組み込みの人々は当然のことながらデバッグを行う傾向があります...それをうまく実行できない人々のほとんどは長続きしません(または単に特定の機能の理由として「ファームウェアが難しい」と単純に受け入れる大企業で働く)年遅れです)

あなたは、プラットフォームごとにターゲットへの可視性の程度が異なる、開発システムの外部システムで実行されるコードに取り組んでいます。自分の管理下にある場合は、開発支援を求めて、ターゲットシステムの可視性を向上させます。デバッグシリアルポート、ビットバンギングデバッグ出力、有名な点滅ライトなどを使用します。少なくとも、オシロスコープの使用方法を学び、 'スコープでピンI / Oを使用して、特定の関数の開始/終了、ISRの起動などを確認します。 。適切なJTAGデバッガーリンクの設定方法や使い方を学ぶことに煩わされることがなかったという理由だけで、必要以上に文字どおり何年も苦労している人々を見てきました。

PCと比較して、どのようなリソースを持っているかを正確に把握することの方がはるかに重要です。データシートを注意深くお読みください。あなたがしようとしているあらゆるものの資源「コスト」を考えてください。スタックの使用量を追跡するための魔法の値でスタックスペースを埋めるなど、リソース指向のデバッグトリックを学びます。

PCと組み込みソフトウェアの両方にある程度のデバッグスキルが必要ですが、組み込みソフトウェアの方がはるかに重要です。


5

あなたのC ++エクスペリエンスはPCベースであると思います。

プログラマーがPCからマイクロコントローラーに移動するときによくあるエラーは、リソースがどれほど限られているかを理解していないことです。PCでは、100 000エントリのテーブルを作成したり、1 MBのマシンコードにコンパイルするプログラムを書いたりしても、誰もあなたを止めません。
あります特にハイエンドでは、メモリリソースの富を持っているマイクロコントローラは、それはあなたがするために使用されます何からまだ遠い叫びです。趣味のプロジェクトの場合は、常に最大限の努力をすることができますが、プロのプロジェクトでは、安価なため、小さいデバイスでの作業を強いられることがよくあります。 あるプロジェクトでは、TI MSP430F1101を使用していました
。1KBのプログラムメモリ、128バイトの構成フラッシュ、128バイトのRAM。プログラムが1Kに収まらなかったため、構成フラッシュに23バイトの関数を書き込む必要がありました。これらの小さなコントローラでは、バイト単位で計算します。別の機会に、プログラムメモリが4バイト小さすぎました。ボスは、より多くのメモリを備えたコントローラーを使用することを許可しませんでしたが、代わりに、既に最適化されたマシンコード(すでにアセンブラーで作成されています)を最適化して、余分な4バイトを収める必要がありました。

作業しているプラ​​ットフォームによっては、非常に低レベルのI / Oに対処する必要があります。一部の開発環境はLCDに書き込む機能を備えていますが、他の開発環境では自分で操作し、制御方法を知るためにLCDのデータシートを最初から最後まで読み取る必要があります。
LCDよりも簡単なリレーの制御が必要になる場合がありますが、マイクロコントローラーのレジスタレベルに移動する必要があります。もう一度データシートまたはユーザーマニュアル。データシートでは、ブロック図にあるマイクロコントローラーの構造についても知る必要があります。マイクロプロセッサの時代に、プログラミングモデルについて話しました、これは基本的にプロセッサのレジスタのラインナップでした。今日のマイクロコントローラーは非常に複雑なので、すべてのレジスターの説明は100ページのデータシートの最も良い部分を占めることができます。IISPは、MSP430のクロックモジュールの説明だけで25ページの長さでした。

多くの場合、リアルタイムのイベント処理を処理する必要があります。中断あなたは10以内に処理する必要が例えば、S、および同じタイミング精度を必要とする別の割り込みを持っている時に。 μ

マイクロコントローラは、多くの場合Cでプログラムされています。C ++はリソースを大量に消費するため、通常は使用されません。(マイクロコントローラーのほとんどのC ++実装は、C ++の限定されたサブセットを提供します。)前述のように、プラットフォームによっては、開発時間を大幅に節約できる関数の広範なライブラリーを使用できる場合があります。少し時間をかけて検討する価値があります。何が利用できるかを知っていれば、後でかなりの時間を節約できる可能性があります。


私はAtari 2600のゲームを書きましたが、これはかなり限定されたプラットフォームです。私が最初に公開したゲームは基本的に4Kコードでした(32Kカートを持っていたので、いくつか追加の機能を追加しましたが、4Kバージョンは完全にプレイ可能でした)。RAMは128バイトです。私がそのゲームを書いた年(2005年)に、文字通り100万倍も大きい他のゲームが公開されたことを考えると面白いと思います。
スーパーキャット、2011

@supercat-ええ、それは予想されていましたが、2005年のAtari 2600はすでに200年前のものでした。私はFPSのようなアクションゲームをプレイしたことがありませんが、それらをプレイするために必要なものを見ると、GPUはプログラム的にも電気的にも、CPUよりもはるかに強力であり、頭を振るしかありません:-)。私は16k TRS-80 IIRCでチェス(サルゴン)をプレイしました。兄のFlight Simulatorにはこれ以上必要ありませんでした。
stevenvh

まだ200歳ではありません。それは1977年にデビューしたので、それは30年でさえありませんでした。それは技術用語で昔のことであると私は同意しますが、100倍の増加も1000倍の増加もないという事実に私はまだ驚いています、しかしRAMとコードサイズの両方で数百万倍の増加。2600は1.19MHzであり、新しいシステムは低GHz帯にしか存在しないため、速度はそれほど向上していません。サイクルごとに2600よりもはるかに多くの処理を実行できます(サイクルごとにビデオラインの1/76を生成する可能性があり、また生成する必要がありました)が、1,000,000倍の速度ではないと思います。
スーパーキャット、2011

3

「ハードウェアプログラミング」には多くの意味があります。非常に小さなチップ(10F200、512命令、数バイトのRAMなど)のプログラミングは、電子回路の設計とほとんど同じです。一方、大きなCortexマイクロコントローラー(1 Mbフラッシュ、64 kB RAM)のプログラミングは、大きなGUIツールキットを使用したPC / GUIプログラミングによく似ています。優れた組み込み/リアルタイムプログラマーである私見には、ソフトウェア開発側と回路設計側の両方のスキルが必要です。より大きなuCの場合、C ++は適切な言語の選択です。非常に小さいものの場合、Cが唯一の選択かもしれません。アセンブリの知識は便利な場合がありますが、深刻なプロジェクトを完全にアセンブリで行うことはお勧めしません。

私は(SWIとEE)の両方の側の人々と深刻な組み込み作業を行いました。マルチスレッドプログラミングの経験があるという条件で、私は一般的にSWIの人々を好みます。

あなたの質問は、組み込みプログラミングに飛び込みたいように聞こえます。ぜひそうしてください。低レベルの側面(チップの周辺機器とその周辺のハードウェアとのインターフェイス)については、いくつかの新しいスキルを習得する必要がありますが、それは多くの新しい概念を持たない多くの作業です。プロジェクトの上位層については、既存の知識を利用できます。


1

呼び出すすべてのarduinoライブラリメソッドについて、それを可能にする豊富なC / C ++コードがあり、APIとして使用できるようにパッケージ化されています。hardware / arduino / *ディレクトリにあるarduinoのソースコードを確認すると、AVRマイクロコントローラーのレジスターと直接対話するために記述されたすべてのC / C ++が表示されます。あなたの目的がこのようなものを(ハードウェアに直接)書く方法を学ぶことであるなら、カバーすることがたくさんあります。ライブラリを使用して何かを動作させることを目的とする場合、ほとんどの困難な作業はあなたのために行われ、ライブラリと開発環境は非常に使いやすいので、話すことはあまりありません。

arduino環境または他の環境に適用できるリソースに制約のあるデバイスを操作する場合の経験則:

使用しているメモリの量に注意してください。コードサイズ(フラッシュメモリに移動)と静的RAM使用量(常にRAMに存在するコード内の定数)。スタティックRAMの使用は、見落としがちなので、最初はもう少し重要だと私は主張します。スタック、ヒープ、定数に使用できるのが1000バイトしかないことも珍しくありません。使い方に注意してください。バイトまたは符号なしのchar(それぞれ1バイト)で十分な場合は、整数の長い配列(それぞれ4バイト)のようなものは避けてください。ここでの別の答えは他のいくつかの重要なポイントを非常にうまくカバーしているので、ここで終了します。主に、arduinoライブラリを使用せずに独自の Cライブラリを作成していない場合にカバーすることがたくさんあるということを説明しまし


0

マイクロコントローラーとOOPプログラミングに関しては、それらは正反対のものではありません。すべてのベンダーライブラリがプレーンCであることは事実ですが、すべてのプラットフォームがC ++ OOPもサポートしています。開発者は、その上にC ++高レベルライブラリとデバイスファームウェアをビルドしてビルドできます。良い例は、Arduinoライブラリ、公式およびユーザービルドです-主にC ++クラスです。おそらく、すべてのOOPの利点が組み込み環境で完全に利用できるわけではありませんが、よく知られているC ++とCの利点はここでも有効です。

考え方と考え方に関して、他の回答で述べたように、マイクロコントローラーはリソースに制約のあるプラットフォームです(特にRAMでは速度が遅い)-動的メモリ割り当てのようなもの、C ++例外は通常除外されます。適切なハードウェアが選択されている場合、これらの制限に容易に対応し、他の手法(他のプラットフォームでも広く使用されています)を使用するのは簡単です。

私の見解では、より難しい課題は、組み込みプログラミングに見られるもう1つの余分な側面、つまりタイミングかもしれません。これは、通常、組み込みソフトウェアがリアルタイムイベント、周辺機器ハードウェアを駆動する厳密にタイミングが定められたプロトコル、および一般的なタスク自体を処理するためです(これらは、マルチスレッドアプリケーションなど、他の「高レベル」プラットフォームでも同様です)。

新しいハードウェアを扱うときは、多くのデータシートを読む準備をしてください。「マインドセット」の質問部分に関連している可能性があると思います:)確かに、EEとハードウェアの知識がいくつか必要になります。

また、最近の組み込みソフトウェア開発では、アセンブリ言語は必要ありません。実際、Java(BTWはデフォルトでOOPです)はすでにここにあり、さらに強力になっています(少なくともIoTデバイスなどの一部のクラスの組み込みデバイスでは、将来は非常に明るいかもしれません)。


懸念の面では、動的メモリ(再)割り当てに関するものは、タイミングよりも従来のOOに対する大きな障害になる傾向があります。
クリスストラットン2016

多分あなたは正しいです。しかし、MSDOSリアルモードソフトウェア用に80〜90年代に64K(データメモリセグメント)のRAMスペースを利用できるようにプログラミングした人がいて、それは「自然」でした。MSDOS PCは、今日のSTM32F4よりも「組み込み」環境だったのかもしれません:)
Flanker

STM32F4は通常、フラッシュの形でより多くのプログラムメモリを備えていますが、PCは通常、可変ランタイムオブジェクトを格納するためにはるかに多くのRAMメモリを備えていました。セグメント化されたアドレッシングによって引き起こされる遠いポインタのすべては苦痛でしたが、どちらも真のMMUを欠いており、それはSTM32F4であるRAMが少ないシステムではさらに大きな問題になります。また、PCの稼働時間は短くなる傾向があり、許容可能な故障率は高くなります。
クリスストラットン2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.