今週末、サンクトペテルブルクで次のカオスコンストラクションフェスティバルが開催され、ファン、プログラマー、開発者が集まってデモ作成の技術を競い合いました。
オーガナイザーのWebサイトでデモとは何かを読むことができます。 要するに、参加者には、スペクトルまたは同様のレトロなハードウェアで印象的な何かをするタスクが与えられ、同時に、プログラムのサイズとデモの期間に制限が課されます。 たとえば、 Spectrumでこれに感銘を受けました。256バイトしかありません。 はい、デモは大きなスクリーンに素晴らしい音で表示されるので、光景は印象的です!
私たちの会社はこのフェスティバルを後援し、同僚と私はハードウェアハックコンテストを開催しました。このコンテストは、プロセッサアーキテクチャを決定することを目的としており、最小限の知識と控えめなツールセットです。
コンテストの開催方法、どのように、どのように準備したか、そして私の記事になります。 猫の下で誰が気にしてください。
そのため、ハードウェアハックの競争の目的は、プロセッサアーキテクチャを決定することであり、プロセッサアーキテクチャと控えめなツールセットについて最小限の知識しか持っていませんでした。 建築の発掘後、元のプログラムまたは独自のプログラムに変更を加える必要がありました。 最終的に、費やされた時間と何が起こったのかというすごい要因が推定されました。
重要なニュアンス-「プレイヤー」の手の中には、普通のコンピューターではなく、鉄片(さらにはレトロ)が入っているはずです。 そして、彼らが言うように、「手元にあるものを使用し、自分自身を別のものに探してはいけない」。 そこで、 Berkut-ETデバイスからマザーボードを取り出し 、ファイルで少し作業し(フライスカッター、ドライバーなどで少し作業し)、通常のデバイスの代わりにクールなガジェットを取得しました。
反対側では、これ(1GイーサネットとFPGAでインターフェースボードを接続しませんでした):
アーキテクチャとボードの内部について少し
ボード上では、ボードはかなり古いものです(実際、新しいBerkut-ETには、より最新のARMプラットフォームが既にあります)。
- AVR ATmega256 8 MHz +最大40キロバイトのメモリ(外部チップが32に接続され、内蔵の8)および256Kプログラム!
- FPGA Cyclone II、パラレルバス(独立したチップセット)を介してAVRに接続、5000ロジックセル
- 8色モードで動作するLCD 320x240(下記参照)、FPGAに接続
- FPGAマトリックスキーボード
- 8個のLED
- ビープ
- FTDI USB-UARTコンバーター
コントローラーに現在のような周辺機器が開発されていなかったため(何年も前には何も知りませんでした)、FPGAでできることをすべて開始し、必要に応じてインターフェイスをプログラミングしました。 FPGAの周辺には、LCD、LED、キーボードがあります。
AVRリソースは非常に限られています-彼はすでに百万の測定管理タスクなどを持っています。 もの。 したがって、FPGAにはグラフィックスコントローラーがあります。
ただし、機能が豊富なため、ボトルネックが1つあります。それは、フレームバッファのメモリ容量です。 わずか8色で十分です。 したがって、各ピクセルには3ビットが使用され、最適なメモリ使用のためにバイト単位で適切にパックされます。
状況はキーボードでも同様です。FPGAはマトリックスにパルスを生成し、クリックを監視します。プロセッサは、押されたボタンに関する割り込みとステータスレジスタのみを取得します。 また、ダイオードを使用すると、プロセッサはFPGAレジスタに書き込み、レジスタ出力はすでにダイオードに接続されています。
アーキテクチャ(拡大)は次のとおりです。
しかし、何か、私は建築に興味を持ちました。 私は、読者にとってブラックボックスにならないように、展示のアイデアを伝えたかっただけです。
したがって、私たちはすでに競技に必要なすべてのI / O周辺機器(最大5つ)を備えた鉄片を持っていて、フォーマットに非常に適していました。
そして、リバースエンジニアリングとは何ですか?
計画どおり、「発掘」用のプロセッサを提供する必要がありましたが、そのアーキテクチャは事前に参加者に知られていませんでした。 実際、これは、メモリ、変数、スタックなどを調査できるツールを提供する必要があることを意味していました。 そして、その内容、したがって、アルゴリズムを変更して実験します。 AVRのデバッガーを提供するのは面倒で退屈な決定のように見えました-結局、掘るのに3時間しかかからず、デバッガーとコンピューターを各ボードに接続したくありませんでした...
そして、独自の軽量スタックインタープリターを作成することにしました。これは、スタックおよび数学/論理演算の操作に加えて、グラフィックプリミティブを画面に表示し、LEDをきしみ、「点灯」させることができます。 正確にスタックする理由 私たちには非常にシンプルに思えました。また、限られたコマンドセットだけでなく、コマンドシステムを拡張するための透過的なインターフェイスを使用して、次のようなことをしようとするのも興味深いことでした。
さて、メモリを「ピッキング」するために、デバッガを作成することにしました。 ささいなことは何ですか:大人のようにやってください;)
スタックインタープリターについて少し
この記事では、スタックインタープリターについて詳しく説明するつもりはありませんでした(詳細を知り、コードとコンパイラーについては別の記事を書きます)。 私は短い遠足に自分自身を制限します。
スタックインタープリターはプログラムメモリを読み取り、オペレーションコードに応じて、スタックの最上部で特定のアクションを実行します。 原則として、1-2-3はスタックの最上部から取得され、めったに4つの値(および一般的な場合、好きなだけ)が取られ、操作の結果はスタックに戻されます。 このアーキテクチャは非常に簡単に実装でき、プログラムだけではありません。
この場合、「馴染みのある」レコードがないため、プログラムはやや異常に見えます(逆ポーランド語が代わりに使用されます)。 たとえば、2つの数値を合計するには、「スタックに数値を入力する」2つの操作を実行してから、「合計」操作を実行する必要があります。 その結果、合計結果がスタックの最上部に表示され、スタックから2つのオペランドが削除されます。 要するに、脳は少し休憩する必要があります。
Funfteスタックインタープリター
インタープリターの場合、最も必要なコマンドセット(合計で20を少し超える)を使用しました。
- スタックを操作する(プッシュ、ドロップ、スワップなど)
- 数学演算用(add、sub、mul、inc、decなど)
- 条件および遷移(if、jump、cond。jump)
- そして、もちろん、スクリーンへの出力のために、スクイーカーとダイオードへ
このセットを使用すると、サイクル、条件付き遷移、カウンターの増分、およびその他の重要な構成を整理できます。 関数の定義から(forth'eのように)拒否しました
すぐに、複雑にならないように。 後で判明したように、変数も実装しませんでした-無駄に。
最初に、彼らは通常のLinuxマシン用にCでインタプリタを作成しました。 同時に、Pythonでテキストコマンドをバイトコードに変換する「コンパイラ」が登場しました。
インタープリターを使用すると(ちなみに、4番目は「4番目」、英語の「5番目」は既に別のインタープリターの下にあるのでfunfteと呼ばれます)、すべてが明らかになったとき、デバッガーを開発し、すべてを結合するだけでした。
デバッガー:16進数のみ、ハードコアのみ!
ここに、私たちが行ったことがあります(参加者にとって、すべてができるだけ混同されるべきであることを忘れないでください、したがって、画面自体に署名がないことができます):
funfteにはプログラムとスタックの2つのメモリ領域しかないため、デバッガには2つの列が自動的に表示されます。 最初の-メモリプログラムのプリントアウト、および2番目の-スタック。 PCは右下に表示され、下部の入力行では、内蔵キーボードからメモリの書き込みおよび読み取りコマンドを入力したり、ブレークポイントとリストを管理したりできます。
もちろん、すべての数字は16進数です。
デバッガーコントロールとコマンドエントリをボタンに移動しました。
- F1-再起動、入力されたプログラムを最初から実行
- F3-続行
- F4-次へ
- Enter-入力されたコマンドの実行
- 0..9-数字と文字を入力します(プッシュボタン電話の場合)
- X-入力された最後の文字を削除(バックスペース)
- 再起動(右側のボタン、写真では見えません)-デバイスを再起動して初期状態を取得します
そして、デバッガーは最も必要なことを教えました。
- ステップごとにプログラムを実行(次):F4ボタン
- ブレークポイントのインストール:b addr
- ブレークポイントを削除:d addr
- 実行を続ける:ボタンF3に進む
- メモリに値を書き込む:w addr data
- プログラムカウンターの変更:p new-pc-value
- メモリ内のアドレスで始まるリストを作成します:l addr。 ソースは、lコマンドの後、プログラムの実行が継続した場合、アドレスp cから自動的に実行されます。
その結果、すべてがエンコードされてAVRに転送されたとき(もちろん、キーボード、ダイオード、LCDコントローラー、多くの既製のオブジェクトを含む「ネイティブ」プロジェクトのすべての成果を使用しました)、結果の言語で簡単な例を記述しました。ダイオード、「DEMO」という行を表示し、緑色の立方体を画面上で左から右へ、そして後ろへ走らせます。
やったー! そして、これはインタラクティブにどのように見えるかです
祭りの初日
8月29日土曜日、5つのステッチされたデバイスで、混withとした構造になり、ハックスペースゾーンに落ち着きました。
私たちを喜ばせたのは、私たちの不思議なデバイスが焼けたメモリー・ディガーの手に落ちたため、コンテストの公式開始を待つ時間すらありませんでした。
私の同僚と私は非常に複雑な何かを思いつき、誰もそれを理解することができないことを非常に恐れていました。 そして、幸いなことに、彼らは間違っていました! 10分後、参加者の1人が表示された長方形の色を変更し、「スタック」、「フォート」などについてささやき声を出しました。
そして、1時間後、左から右へ、そして後ろへ移動するはずの長方形が動作を変更しました(もちろん、それ自体ではなく、競争の勝者の1人の助けを借りて)。 これを行うには、コマンドのリストを逆にし、アルゴリズムを理解し、長方形がX座標を変更するサイクルで、Y座標を変更する必要がありました。
さらに、ハッカーはテーブルにメガプロセッサからのコマンドの完全なリストをすでに持っていました。これには、例では使用されなかったコマンドも含まれています。
次の呼び出しで、2時間の発掘の後、彼らは私たちにプログラムが16バイトだけフラッシュされたデバイスを与えました
そして、もう一つの興味深い作品があります:
初日の結果:10人以上が参加し、ほぼ全員が管理されました。 いいね!
祭りの二日目
さて、翌日、タスクをわずかに変更することにしました。
これで、コマンドのシステム全体と、すでにそこにあるもの、インタープリターコードが参加者に公開されました。 印象的な何かを書くことが必要でした。 繰り返しになりますが、結果は予想を上回りました。githubで数時間後に、インタープリターの4つの新しいコマンドのプルリクエストが既にあり、スタックとメモリ内の任意のセルにアクセスできました。 つまり 実際に変数を宣言する機会。 彼らは確かに名前を持っていなかった、彼らは住所を覚えていなければならなかったが、それでも。
ファームウェアをフリーズ、アセンブル、アップロードした後、実行中に独自のコードを変更する新しいデモを入手しました。 彼女は52バイトを獲得し、競争で2位になりました。
また、2日目には、いくつかのバグを見つけて修正することができました。多くの参加者に感謝します。
受賞者の授与
一日の終わりに、フェスティバルの公式終了時に、受賞者に賞品を贈呈しました。
もちろん、賞品も手作りです。
少し結論
結論として私が言いたいこと。 クールな運転イベント、フェスティバルに参加する機会、そして本当に情熱的な人々とのコミュニケーションの喜びに感謝します。 私たちの競争に参加してくれたすべての人に感謝します。私たちが無駄にしようとしなかったことを非常に喜んでいます。 もちろん、この形式のインタープリターはあまり実用的ではありませんが、興味深い詳細の90%が開発者から隠されている高レベルのプログラミングから脱出し、記憶と注意を少し訓練し、何か新しいことを学び、楽しむことができます。
そして、もちろん、競争に備えるためのチームワークについて同僚に感謝します。
PS:私たちは1つの大きな省略をしました:ブザーを完全に制御しませんでした。 持続時間のみを制御できるようにしましたが、それでも周波数制御を設定する必要がありました。 その後、デモを音楽で行うことができます。 まあ、何も、来年は追いつきます!