3

私は、いくつかのインターフェイス (ボタン、Bluetooth、ハプティック ノブ) を備えたモーター コントローラーを作成しています。低レベルのモジュール (I2C バスで通信するためのコードを書くなど) から始めて、それより上位のモジュール (I2C バス上の特定のデバイスと通信するためのコード...)から始めようとしましたが、対応できなかった癖を処理するために、下位のモジュールに戻る必要があることがよくあります。これには長い時間がかかるか、本当にハックっぽいコードが表示されます。

私のターゲットは 8 ビット MCU であるため、ボトムアップでハードウェアをより有効に活用できるようです。トップダウンに行くと、構築またはテスト/デバッグするための構造がありません。

全体的なダイアグラムと特定のレベル/ドライバー用のダイアグラムをいくつか作成してみましたが、それらをどのように構成すればよいかわかりません。そのため、非常に体系的になり、2 ~ 3 まで上昇する必要がある奇妙な信号を見逃さないようにすることができます。レイヤー。

これがCSの学位の理由だと思いますか?私は電気技師です:P

4

7 に答える 7

3

多層コードで作業している場合、API ではやりたいことを正確に実行できない場合、下位層に飛び込みたくなることがあります。これは、複数の層を同時に書き込む場合に特に困難です。

以下にいくつかの提案を示します。

  • 作業中の階層以外のすべての階層は、封印されているものとして扱います。別の会社、開発者などによって作成されました。現在の層の問題を解決するために別の層を変更したいという衝動に抵抗してください。
  • 作業中の階層に「兄弟層」を作成します。これを抽象的な意味で説明するのは難しいですが、下位層がビジネス層で、上位層が UI であるとしましょう。別のアプリケーション用に別の UI 層を作成します。同じ API の 2 つのコンシューマーを持つことで、各レイヤーに何が必要かを指摘するのに役立ちます。
  • ティアで作業する順序を交互に変えてみてください。たとえば、一部のアプリでは、最初に UI を設計し、次にビジネス レイヤー/データベースに進んでその UI が設計どおりに機能するようにする方が便利だと思います。それ以外の場合は、データ モデルを使用して統計を作成し、UI まで作業する方が理にかなっています。しかし重要なのは、これら 2 つのシナリオでは、API の "考え方" が異なるということです。そして、多層コードを両方の角度から見てきたことが役に立ちます。
  • 経験が重要です。場合によっては、過度に結合されたコードの間違いを犯すことが、それを回避することを真に学ぶ唯一の方法になることがあります。アプリが完璧であることを計画するのではなく、不完全であることを計画してください。つまり、最初に迅速な開発/テスト/リファクタリング サイクルをセットアップして、間違いを犯した後でなければ見られない間違いにすばやく適応できるようにすることを意味します。ここでも「使い捨て試作」が活躍します。簡単なラフ案を作成し、それから学び、それを捨てます。捨てる部分が大事。たとえそれが素晴らしいものであっても、別のものをゼロから構築し始めてください。プロトタイプから学んだことに基づいて、必然的にそれを改善します (そして、私の経験では、より組織化されます)。
于 2010-08-12T22:27:14.367 に答える
3

あなたは正しい軌道に乗っているように聞こえます。いくら計画を立てても、後でシステムの一部を再設計またはリファクタリングする必要がなくなる場合があります。次のヒントを試してください。

  • 論理関数で区切られたモジュールにコードを保持します。
  • コードを複製しないでください。代わりに、共有機能の再利用可能なメソッドを設計してください。
  • 特別な場合にハックを追加する誘惑を避けるようにしてください。最終的にこれは維持できなくなります。代わりに、できるだけ早く小さなセクションを調整してリファクタリングしてください。最後に大規模な再設計を行おうとすると、より困難になります。
  • 最初からシステムを過度に設計しようとしないでください。実際の実装に到達したときに時間を無駄にしている可能性があります。
  • 下位レベルをできるだけシンプルに保ち、その上により高度な機能を構築します。
  • 特に複雑な条件ステートメントを追加した後は、関数を文書化し、いくつかの単体テストを記述します。
  • スタックのできるだけ高い位置でエラーをキャッチするようにしてください。たとえば、入力の検証を行い、戻り値をチェックします。これにより、デバッグが容易になります。
于 2010-08-12T23:07:53.820 に答える
2

学歴よりも経験が問われます。ハードウェアの制御方法についてまだ学んでいるのであれば、もちろんコードは変更されます。私はそれについて苦悩しません。ただし、実際に行っているのはプロトタイピングであるため、コードが機能するようになったら、コードをリファクタリングする準備ができている必要があります。冗長性を排除し、データと機能を区分化し、インターフェイスを整理して意味のあるものにします。

私の経験では、デバイス ドライバー コードにはトップダウンおよびボトムアップの設計/実装が必要であり、これを私はアウトサイド インと呼んでいます。ユーザーが何をしたいのかを知っていて、それらのインターフェースを書くことができます。また、低レベルのドライバーが何をする必要があるかを知っていて、それを書くことができます。それらが途中でうまく合わない場合は、モジュールのレイアウトを再考してください。

改善のために、設計とコードを経験豊富な人にレビューしてもらいます。自我を捨てて、問題に対する彼らの見解を理解してください。また、オブジェクト指向の分析と設計に関する本を読むこともできます (以前は Peter Coad の本が好きでしたが、今は誰が書いているのかわかりません)。良いものは、問題を明確な役割と責任を持つオブジェクトに分割する方法の例を示します。

もう 1 つは、ドライバーのプロトタイプを作成し、ハードウェアの制御方法を理解したら、詳細な要件を確認することです。作成中に要件を発見すること以上にコードをねじ曲げるものはありません。コードを書く前に、UML を学んだり、ダイアグラムを使ってデザインしたりすることもできます。これは誰にとってもうまくいくわけではありません。また、OOD を使用するために、オブジェクト指向構造をサポートする言語でコーディングする必要がないことにも注意してください。

于 2010-08-12T22:27:25.910 に答える
2

問題が適切な抽象化を構築する方法である場合 (実際にそうであるように思われます)、学ぶためにできる最も重要なことは (設計コードのレビューを依頼する/本を読む/コードを読むこと以外に)、自分の前でよく考えることだと思います。コードの書き込みを開始します。

通常、何が必要で、どのように実行するかの大まかなアイデアから始めて、コードを書き始めます。後になって、よく考えていなかったことに気付き、コードの記述に時間を費やしたためにパッチを当てるのが難しく、時間の浪費やハッキーなコードにつながる大きな穴がいくつかあることに気付きます。

変化に対応しやすいデザインを作るにはどうすればよいか、よく考えてください。たとえば、レイヤー間を移動する必要があるデータをカプセル化することで、後で重要なパラメーターを見逃したことに気付いた場合でも、どこでもコードを変更することなく、構造に簡単に追加できます。

最も重要な詳細を考慮したことを合理的に確信できるまで、何度か「頭の中で設計を実行する」ようにしてください (これは最も重要な部分です。常に何かを見落としたり、要件が変更されたりするためです)。何かを見逃した場合でも、比較的簡単にモジュールを微調整できます。

UMLは、設計について考える方法を構造化するのに役立ちます。これは確かに万能薬ではありませんが、ソフトウェア設計を作成する際に考慮すべきさまざまな基準を示しています。

それは古典的なチェスの先生のアドバイスに少し似ています:「あなたの手に座ってください」:-)

于 2010-08-12T22:39:58.223 に答える
1

ドライバーはレイヤーアプローチに適しています。

ドライバーはいくつかの「クラス」を持つことができます:

  • 入力のみ
  • 出力のみ
  • IとOの両方。

標準化されたインターフェースが必要です。たとえば、次のようになります。

GetKnobLevel()
GetNextKeyboardButton

または、別のアプローチは、次のようなものを持つことです

syscall(DRIVERNUMBER, command)

パラメータ/結果を指定されたレジスタに入れる。

シンプルで使いやすいアプローチです。より複雑なバリアントは、レジスターの代わりに、ハードウェア通信コードとソフトウェア通信コードの間に循環キューを持つことです。

私が使用しているメンタルモデルは次のとおりです。

---
Application
---
OS
---
Driver communicators
---
drivers
---
hardware

各レイヤー間には、厳密に定義された分散のないインターフェイスがあります (レイヤー間に厚いフロスティングがあるレイヤー ケーキを想像し続けます...)。もちろん、OS が存在しない場合もあります。

MCU が x86 CPU のようなソフトウェアとハ​​ードウェアの割り込みをサポートしている場合は、それらを使用してドライバーをドライバー コミュニケーターから分離できます。

正直なところ、これは少し「オーバーエンジニアリング」なソリューションです。しかし、複雑さが著しくなる状況では、緩いエンジニアリングよりもタイトなエンジニアリングの方が簡単です。

レイヤー間で通信している場合は、通信「チャネル」ごとにグローバル変数を使用し、関数のみを使用してアクセスすることで、統制された方法でアクセスできます。

通常、実際にプロジェクトのコードを書き始める前に、ある程度の紙の設計、探索的な作業、および再設計を行います。ここでは、フローチャートとバス遷移図がうまく機能します。

これは、組み込みシステムの作業で私が好んできたアプローチであり、うまく機能しています。

また、この問題領域は、従来のコンピューター サイエンスのカリキュラムでは十分に調査されていません。Web や最新のオペレーティング システムよりもはるかに寛容ではありません。

于 2010-08-12T23:12:52.600 に答える
0

おしゃべりではありませんが、The Mythical Man-Monthからの引用が頭に浮かびます。

その当然の帰結は、「うまくいくようにする。正しくする。速くする」ということです。

これにより、事前に何らかの設計を行うことを支持するようになると思いますが、それによって麻痺することはありません。最初から完璧である必要はありません。リファクタリングを計画します。うまくいけば、実際には多くのコードを捨てるのではなく、より快適な方法で物事を再配置するような方法で物事を書いていることでしょう。

于 2010-08-16T16:10:06.743 に答える
0

私の意見では、よく構築されたコードの最も重要な側面は、結合度が低く、状態からの副作用の分離です。

また、コードは工芸品です。最初から完璧なソリューションを作れるとは思わないでください。新しいことを学んだら、コードを変更する準備をしてください。実際、自分の仕事の一部として自分自身を変えることを受け入れるようにしてください。

于 2010-08-12T22:59:31.063 に答える