前回作成したLED点滅回路では、GPIO(汎用I/O)からLEDに向けて信号を出力するようにしています。本記事ではVitisとVivadoを用いてZybo上の"LED"を点滅させるアプリケーションを作成しています。CPUで動作する”LED点滅”プログラムの動作原理を解説しながら、実際にLEDの点滅まで確認しました。GPIO”のレジスタに直接値を書き込むことによってLEDを点滅させました。GPIO”をインスタンスとして扱って、ドライバAPIを活用してみようと思います。GPIO”のドライバAPIの使用方法について学んでいきたいと思います。統合ソフトウェア開発環境VitisとFPGA設計環境Vivadoにおけるインスタンスの概念とGPIOのドライバAPIの使用方法について理解するインスタンスの概念についてGPIOのインスタンスXSAファイルを読み込んで作成したVitisのプラットフォームプロジェクトには、xgpio.hというヘッダファイルが含まれています。xgpio.hでは次の2種類の構造体が定義されています。XGpioxgpio.hにおける2つの構造体のうち、構造体XGpioにより宣言された変数は「インスタンス」と呼ばれています。GPIOのIPコアであるかのように、アプリケーション上での一つの対象として扱っています。このようにIPコアをアプリケーション上でも仮想的に扱うために宣言した変数は、実際のデバイス上で実体を伴った対象であることを考慮し、「インスタンス(実体)」と呼ばれています。以下では、具体例を見ながら、インスタンスの概念と取り扱い方について確認していきましょう。ちなみに、構造体XGpio_Configはデバイスのハードウェア設定を一つにまとめています。インスタンスとコンフィグレーションに含まれる変数は重複することも多いですが、ドライバAPI上では用途によって引数を区別しているようです。インスタンスの具体例ドライバAPIにおける各機能をもつ関数の引数にインスタンスを設定することによって、実際のIPコアを制御することができます。以下のコードを見ていきましょう。/*略*/}まず、main関数外で、LEDInstというXGpioのインスタンスを宣言しておきます。宣言しただけでは、まだ実際にデバイス上に存在するIPコアとはなんの対応もついていません。GPIOのベースアドレスをセットにして、API関数XGpio_Initializeを実行します。IPコアとして扱うことができるようになります。実際にインスタンスを使ってIPコアを制御するイメージを、XGpio_SetDataDirectionというAPI関数を例に確認してみましょう。(GPIOx_TRI)」と呼ばれる制御レジスタを書き換える関数です。GPIOx_TRIレジスタでは、GPIO信号を入力にするか出力にするかを切り替えています。前回レジスタを直接変更した場合の、コントロールレジスタに対応しています。レジスタに0を代入するとGPIOのI/Oピンは出力方向を向き、1を代入すると入力方向を向きます。LED点滅アプリケーションの例では、LEDに信号を出力させるわけなので、レジスタには0を代入します。前回、コントロールレジスタ[LED_ctrl]に値[0x0]を直接格納しましたが、XGpio_SetDataDirectionという関数を使えば同じことを行うことが可能です。GPIOのチャネル番号1と入出力方向0x00をパラメータとして代入します。GPIOには2個の入出力I/Oを設けることが可能で、その2つをチャネルと呼んで区別しています。チャネル番号は1と2を選択できますが、今回は1つしか使っていないので1を代入しています。XGpio_SetDataDirection()機能:ある特定のGPIOチャネルの個々の端子における信号の入出力方向を設定する。2)・DirectionMask:どの端子を入力(1)、出力(0)にするかを定めるビットマスク。例)LED[3:0]のうち、仮に上位2ビットを入力、下位2ビットを出力にしたい場合はDirectionMaskに2進数で[1100]、つまり16進数で0x0cを代入する。返り値:なしインスタンスを使うポイントは、API関数XGpio_SetDataDirectionを使うときに、デバイス側のID情報などのハードウェアに関する特性を、アプリケーション開発者が直接は参照していない点です。ベースアドレスはインスタンスに含まれており、API関数を使えばハードウェアのどのレジスタを叩けばよいかということは意識する必要がなくなります。GPIOというIPコアを意識せずに、API関数だけで制御できるのが、インスタンスという概念でデバイスを抽象化するメリットになっています。ドライバAPIの中を見てみようひがしただ、筆者はハードウェアがどうやって動いているのか気になってしまい、隠されているドライバAPI関数の中を関数を使う前に覗くことが多いです。今回もせっかくですので見てみましょう。Xilinxから提供されるソースコードの中を参照しました。ソースコードはgithubからお借りしています。XGPIO_TRI_OFFSET,DirectionMask);}主に2つの関数Xil_AssertVoidとXGpio_WriteRegが使われているようですね。Xil_AssertVoidは引数がfalseの場合に警告を発する関数で、ドライバAPIの関数が正しく使用されているかを監視しています。XGpio_WriteRegはGPIOの特定のレジスタに値を書き込む関数です。実際にどんどん階層を深くたどっていくと、結局前回の記事でやったのと同じようにレジスタを直接叩いている関数であることがわかります。XGpio_WriteReg()機能:GPIOレジスタに値を書き込む。パラメータ:・BaseAddress:GPIOデバイスのベースアドレス・RegOffset:ベースアドレスから書き込むレジスタのアドレスまでのオフセット・Data:レジスタに書き込むデータ返り値:なしひがしもちろん、レジスタに値を書き込むだけの単純な処理であれば、直接アドレスに値を書いたり、レジスタを意識したXGpio_WriteRegを使うことも可能です。機能が複雑になってくると、インスタンスとして抽象化し、より機能を限定かつ明確にしたXGpio_SetDataDirectionという関数を使ったほうが、アプリケーション設計者にとって可読性が高く理解しやすいコードを書けるようになります。以下は、前回作成した”LED点滅”アプリケーションを、GPIOのインスタンスを用いて書き換えたコード例です。このコード例を見ながら、関連するドライバAPI関数の機能を確認していきましょう。0;}コードの解説このコード例で、新しく追加したドライバAPI関数はXGpio_DiscreteWriteです。この関数もレジスタに値を書き込む関数ですが、XGpio_SetDataDirectionとの違いはデータレジスタに値を書き込む点です。}XGpio_DiscreteWrite()機能:ある特定のGPIOチャネルの、個々のデータレジスタに値を書き込む。2)・Data:端子に書き込む値。例)LED[3:0]のうち、仮に上位2ビットをHigh(1)、下位2ビットをLow(0)にしたい場合はDataに2進数で[1100]、つまり16進数で0x0cを代入する。返り値:なし前回の記事では、以下のように定義したLEDというデータアドレスに直接値を代入していました。0;}全く同じことをやっていますが、XGpio_DiscreteWriteというAPI関数を用いたほうが、どういった処理を行っているかがハードウェアの中身を知らない設計者にとっても理解しやすくなります。ひがしちなみに、このソースコードでも前回の記事と同様に、LEDが点滅することを確認できました。インスタンスとは、IPコアをアプリケーション上でも仮想的に扱うために宣言した変数。アプリケーションを作成するときに、デバイスを意識せずにAPI関数だけで制御できるのが、インスタンスという概念でデバイスを抽象化するメリット。ひがしここまで読んでいただき、ありがとうございました。次回の記事へのリンク【LED点滅編(4)】タイマー割り込みを行うAPIについて解説Zynqのプロセッサ上で割り込みをかける方法について解説します。SDKでのAPIの使用方法についてまとめました。Liteのレジスタに書き込む方法IPパッケージャーを使用してMaster側のAXI4-Liteインタフェースを追加する方法を解説しています。Lite”のAXI4-Liteポートと接続可能なカスタムIPを作成しました。TerminalのマイコンとZynqをデータを通信する方法を解説。本記事では、サンプルプログラムや各API関数のリファレンスの参照方法を紹介した後、サンプルプログラムの動作原理について調べた内容を解説します。tanhをうまく応用することによって、FPGA上でも自然対数の計算ができます。今回の記事ではVivado上で自然対数を計算するブロックデザインを作成し、シミュレータで計算精度を確認してみました。本記事ではVitisとVivadoを用いてZybo上の"LED"を点滅させるアプリケーションを作成しています。CPUで動作する”LED点滅”プログラムの動作原理を解説しながら、実際にLEDの点滅まで確認しました。Terminalをマスター、Zynqをスレーブにして、データを通信する方法を解説。本記事では、I2C通信方式について解説した後、マイコンとZynqの接続の構成について解説しました。Zynqが外部からのHDMI信号を受信しDDRメモリに格納した後、DDRメモリを読み出しVGA信号を送信するアプリケーションの解説をZyboを使って行っています。ソースコードを例にHDMI信号を受信する際のAPIの使用方法を解説しました。コメントをキャンセルメールアドレスが公開されることはありません。※サイト次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。上に表示された文字を入力してください。@phys_higashiFPGAを使ったデジタル回路の設計に興味を持ち、休日に勉強をしています。初学者の目線から、詰まりやすいポイントとそれを解決した方法について、記事にまとめています。初学者ゆえの間違い等あるとは思いますが、お気づきの際はお問い合わせをいただけますと幸いです。@phys_higashiFPGAを使ったデジタル回路の設計に興味を持ち、休日に勉強をしています。初学者の目線から、詰まりやすいポイントとそれを解決した方法について、記事にまとめています。初学者ゆえの間違い等あるとは思いますが、お気づきの際はお問い合わせをいただけますと幸いです。-掛け算IPをZyboに実装-2021.04.182022.02.13Rustupをインストールするときに発生したエラーの回避方法2021.08.102021.11.07。