ZynqのPLを操作するLinuxドライバ (ユーザプログラム編)

ZynqのPLを操作するLinuxドライバ (DTS設定編)の続き。これは見た方が早いと思うので、コードを示す。


#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>

int main()
{
    int uiofd;
    int err;
    int i;
    unsigned icount;
    unsigned int* map_addr;
    unsigned int cnt;
    unsigned int ...
more…

ZynqのPLを操作するLinuxドライバ (DTS設定編)

LinuxにおいてZynqのPL部に作成したレジスタを操作するための方法について調査したところ、カーネルドライバを作成する以外に、UIOという枠組みを使用することで簡易に行うことができるということが分かった。これを使用すると、ユーザプログラムでレジスタの読み書きだけではなく、割り込みの検出も行うことが出来る。

まず、カーネルコンフィグにおいてUIOを有効にしてビルドする必要がある。

CONFIG_UIO=y
CONFIG_UIO_PDRV_GENIRQ=y

あたりが最低限必要と思われる。(自分の場合は元から有効になっていたので、カーネルの再ビルドは不要だった。)

次に、デバイスツリーに次のような記述を追加する。自分の場合では、arch/arm/boot/dts/zynq-zed.dtsのamba@0ノードの一番下に追加した。

foo_bar_device: foo-bar-device@44000000 {
                compatible = "generic-uio";
                reg = < 0x44000000 0x4000 >;
                interrupts = < 0 29 4 >;
                interrupt-parent = <&ps7_scugic_0>;
};

まず、compatibleでgeneric-uioと記述する。これが、あらかじめ用意されているカーネル側のUIOドライバを使用するための文字列。こうすることで、drivers/uio/uio_pdrv_genirq.cが使用される。

次に、regにおける ...

more…

ZynqのPLロジックからARMへの割り込み実験

Permalink: 2014-05-13 13:32:00+09:00 by tu1978 in tags: Zynq

Zynq上のPLに作成した回路からARMへ割り込むときに、割り込みレイテンシがどれくらいになるのかを計測してみた。

ZYBOを使用しているので、ARMは650MHzで動作。結論は次の画像:



1クロックは10ns(100MHz)。一番下のIRQがHighになるとCPUに割り込みがかかる。AXIバスを通してレジスタをクリアするとIRQがLowになる。これを見ると、たったの31クロック(=310ns)で割り込みがクリアされている

これはStandalone(Linuxではなく、ベアメタル)で実験した。割り込みを有効にする部分だけ、参考に貼っておく。

Status = XScuGic_Connect(IntcInstancePtr, XPS_FPGA0_INT_ID,(Xil_ExceptionHandler)IrqHandler, NULL);
    if (Status != XST_SUCCESS){
        return Status;
    }
XScuGic_Enable(IntcInstancePtr, XPS_FPGA0_INT_ID);

これでXPS_FPGA0_INT_ID(61)番の割り込みが発生すると、 IrqHandler関数が呼ばれる。IrqHandler関数の中で、PLロジックにアクセスして、割り込みをクリアしている。

more…

Zynq上でのLinuxアプリケーションのデバッグ方法

やっとZYBO上でLinuxが(Ethernetも含めて)動作するようになった。これについては別の記事でまとめることにするが、一番気になっていたのは、LinuxアプリケーションのデバッグがXilinxのSDKから簡単に可能かどうかだった。

現在(2014.1)のSDKにはGDB, System Debuggerという2種類のデバッグ方法が用意されている。GDBでのデバッグは可能だったが、System Debuggerでは出来なかった。こちらのビデオによると、System DebuggerでLinuxアプリケーションをデバッグしている。スレッド単位でブレークを掛けたりすることもできる様子で、なかなか強力だと思う。

一方、System Debugger Limitations, Known Issues, and FAQsによると、2013.4の時点ではSystem DebuggerでのLinuxアプリケーションのデバッグはできないように思われる。2014.1については情報は見つからなかった。

上記のビデオでは実現できていることからすると、これが可能になったのはごく最近のことであると思われる。ビデオをよく見てみると、Yocto Linuxが起動しているのが分かる。また、TCF(System Debuggerが使用するフレームワークの仕様)のためのagentが最後の方で起動しているのも分かる。

とりあえず自分の要件としてはGDBでも良いが、System Debuggerについても時間があるときに調査してみたい。

また ...

more…

Linux on Zynq (ZYBO)

今度はZYBOにてLinuxを動作させてみようと挑戦した備忘録。

まとまった情報がなかなか見つからなくて苦労したが、基本はMasahiro Yamadaさんの、"U-Boot と Linux Kernel のメインラインで Zynq を動かす"を参考にした。

STEP0: DTCの準備 はそのまま実施した。

STEP1: U-Bootのビルド ではまった。結論としては、ARMのクロスコンパイラとしてCodeSourcery Liteを使用した(単にXilinxからgccをダウンロードするのが面倒だったので。Xilinxのgccで動くかは試していないため不明)。

最初はLinaroのGCCでU-Bootをビルドしていたが、どうしても動作しなかった。U-Bootはlibcにも依存しているようで、LinaroのGCCだとダメだと思われる。

さらに、肝心のU-Bootは、オリジナルのものだと動かなかったので、DigilentのU-Bootを使用した。この手順は、Ryuzさんの"ZYBO(Zynq)のu-bootのビルドまで"に従った。CROSS_COMPILEのところは、(CodeSourceryなので)arm-none-eabi-にした。makeでu-boot.binができた(上記手順だとDTBはできないが、Linuxのブートは可能)。

STEP2 ...

more…

Zynq USBデバイステスト (ファームウェア)

Zynq USBデバイステスト (PC側ソフトウェア)の続き。

C:\Xilinx\SDK\2014.1\data\embeddedsw\XilinxProcessorIPLib\drivers\usbps_v2_0 のexamplesに対するパッチ。 usbMain関数を呼び出すと動作開始。examplesのファイル達はusbフォルダにコピーされたものとする。

概要としては、examplesはUSB mass storageとして動作するので、バルク転送のTX/RX割り込みがかかるところを 横取り(XUsbPs_HandleStorageReqをコメントにする)して、所望のデータ処理に置き換える。 また、サンプルはTX割り込みがかからないようになっているので、TXのビットをorして有効にする。


diff -cr examples/xusbps_ch9_storage.c usb/xusbps_ch9_storage.c

examples/xusbps_ch9_storage.c    2014-04-16 23:53:27.579740500 +0900
--- usb/xusbps_ch9_storage.c ...
more…

ZynqでのUSBデバイステスト (PC側ソフトウェア)

Zynqに内蔵されているUSBポートをデバイスモードで使用できるかテスト中。

とりあえず最低限のループバックでは動作したので、汚いがコードを貼っておく。

まずは、WinUSBを使用したPC側のソース。ほぼMicrosoftのドキュメントをくっつけただけ。インクルードの順番だけは結構重要だったりする。winusb.lib, setupapi.libをリンクすること。

ドライバはインストール済みの前提。


#include "stdafx.h"
//#include "usb.h"
#include "windows.h"
#include "usb100.h"
#include "usb200.h"
#include "SetupAPI.h"
#include "winusb.h"
#include "winusbio.h"
#include "strsafe.h"

#define MAX_DEVPATH_LENGTH (1024)

// {9F68AD5A-84E0-4E0F-8EF3-11139532FD22}
GUID GUID_DEVINTERFACE_OSRUSBFX2 = { 0x9F68AD5AUL, 0x84E0, 0x4E0F, { 0x8E, 0xF3 ...
more…

WinUSBのinfファイル

ZynqのUSBデバイス機能を試すためにWinUSBを使用するための備忘録。

WinUSBのドライバファイルはWDKに含まれているので、このあたりからインストールする。 WDK8.1からはVisual Studio 2013を先にインストールしてからWDKをインストールしないといけない、と書いてある。サボって後で面倒になるのも嫌なので、手順に従う。

フォルダを作って、次に示すような感じでinfファイルを作成する。同じフォルダにamd64(64bit Windows7の例)というフォルダを作成し、その中にC:\Program Files (x86)\Windows Kits\8.1\Redist\wdf\x64からWdfCoInstaller01011.dll, winusbcoinstaller2.dll, WUDFUpdate_01011.dllをコピーする。

infファイルの内容(例)。GUID, VID, PIDは適当に修正

[Version]
Signature = "$Windows NT$"
Class = ZynqDeviceClass
ClassGuid={23AEE0D0-4E4B-4B03-8360-1FB07C0C3338}
Provider = %ProviderName ...

more…

ZYBOの実験

先日digilentに注文しておいたZYBOが届いた。

いきなり確認不足だった点:
- VGAポートは抵抗分割のFPGA直結だった。しかもRGB565(計16bit)階調しかない。
-水晶はPSの50MHzが接続されているだけ?と思ったが、マニュアルを読んでみると、ethernet PHYから125MHzが出ていて、それがPL(pin L16)に接続されているみたいだ。こちらは、PHYRSTBをHighにしないと出力されない。

早速、4/25付けで上記ページにアップロードされているZYBO Base System Designをダウンロードし、Vivado 2014.1で合成してSDKで動かしてみた(IPのアップグレードは薦められるままでOKだった)。main.cのAudoInitializeを実行すると、デバッガが止まってしまったので、とりあえず後回しにし、コメントアウトして実行すると、UARTでメニュー操作ができるようになった。

HDMIを選択し、1920x1080@60pを選択すると、ちゃんとFull HD解像度で動作した。

Zynq7010は、デバイスとしては公式には1.5Gbpsはサポートしていないはずだけれど、安定して動作しているっぽいな。Zynq恐るべし。

HDMI出力のところは自分で作ろうかと思っていたのだが、サンプルがこんなに簡単に動いてしまうと、自作する気力は一気に萎えた。別のことに労力を使うことにしよう。

marseeさん ...

more…

最近更新していないので何か書きますよ - AlteraとXilinxのIOについて

Permalink: 2014-02-15 15:36:00+09:00 by tu1978 in tags: FPGA

XilinxとAlteraのFPGAで、特に外部との高速信号をやりとりをするときの考え方の違いについてまとめてみる。ただしGTPなどのGigabit Transceiverは考えない(まだ使ったことがないので)。

Xilinxは、基本的にはIOモジュールにあるI(O)DELAYや、I(O)DDR, I(O)SERDESなどを自分でインスタンス化して使用するのが一般的な方法に思われる。これらを使用することで、動作時に信号のタイミングを動かすことができる。また、これらを使用するとシリアライズ/デシリアライズ部分の回路のタイミングはコンパイル毎にほぼ変化しないので、実際に動作させて、ちょうど良いタップを見つける、ということが可能である。

また、ツールとしても、入出力のタイミング制約は、たとえ掛けたとしても、これらのモジュールの配置制約の方が優先される。したがって、あくまでもタイミング制約は、指示した配置をしたうえで、条件を満たすかどうかの確認の意味しかない。

一方Alteraの場合は、タイミング制約ドリブンで配置配線が可能である。クロックとデータとの関係をちゃんと制約すれば、それを(入力の場合)内部のレジスタで正しくラッチできるようにレジスタを配置配線してくれる。レジスタはIOにあるものを使用するかもしれないし、そうでないかも知れない。また、動作時にIOのタイミングを変化させることはできないようだ(少なくともCycloneは)。ちなみに、AlteraのIOにも、スタティックに遅延量が決定する遅延ブロックが存在する。この遅延量もタイミング制約を満たせるようにツールが自動設定してくれる。

以上から、自分の印象としては、静的にタイミング制約をすることで動作可能な場合はAlteraが便利で ...

more…