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…

高速ビットマップ描画方法を調査

高速にメモリ上のデータをWindowsで表示する方法について調査してみた。

経験上OpenCVは余り高速ではない。OpenGLでテクスチャに貼り付ける、という方法は高速で、プラットフォームにもあまり依存しない方法なのだが、カメラと対象物との位置関係で、勝手に変形されてしまう(これはOpenGLの目的からして当然であるが、ちゃんとデータを1対1で画像ピクセルに反映させたい、というような場合には問題となる)、という問題がある。

また、OpenGLを使用する場合、ウィンドウ管理はGLUTに任せてしまうと、自分で作成するWindows上のウィンドウに描画するときに問題になる(理論上は可能なはずだが、面倒なのであまり調べていない)。

目標としては、Windowsで、自分で管理するウィンドウの内部に、高速にメモリ上のデータを表示したい。

少し調べてみた結果、Vista以降のWindowsであれば、Direct2Dを使用するのが目的にかなっているようだ。もちろんWindowsにべったりになってしまうのだが、仕方がない。

なんとなく、ID2D1HwndRenderTargetでBitmapを作成し、CopyFromMemoryを行ってDrawBitmapという流れで出来そうな気がしてきた。これだとオフスクリーンではないかも知れない。でも、この応用で何とかなりそうな気がする。

今度実験してみよう。

===================
ちなみに、調べてみると、MacではOpenGLのFramebuffer objectという方法があるようだ。自分がWindows上のOpenGLで試したときには、FBOはそれほどパフォーマンスが良くなかった印象がある。Macだとまた違うかも知れないが。

more…

今日の実験 - Media Foundationを使ってWebCamキャプチャ

いわゆるWebCamというものを、自分で作成するプログラムはどうすれば作成できるのか、というのを調査している。

一番手っ取り早いのは、多分OpenCVを使用してcvQueryFrameで取ってくる方法だと思われるが、USB Video Classの機能をもっと使用することを考えているので(Extension Unitsというのを使いたい)、cvQueryFrameは高レベルすぎる。

Windows VistaからMedia FoundationというAPIが提供されており、これを使用するのが推奨のようだ。とりあえずMFCaptureD3D Sampleのページから、サンプルプログラムをダウンロード(Download from MSDN Code Galleryというリンク)し、VS Express for Desktopでビルドして実行したら、正常にWebCamから動画をキャプチャ、表示できることが確認できた。試したカメラはYUV2形式のデータだった。

追記: どうやらExtension Unitsは、DirectShowのAPIのようだ。果たしてMedia Foundationを使ったプログラムでも使用できるのか?よく分からない。さっぱりMedia Foundationは諦めて、DirectShowのサンプルでも探した方が良いかも知れない...

DirectShowのプログラミングには、良い情報源(体系的な資料)が無いような気がする。知っている人は知っているが ...

more…

[Android] Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]の対応方法

Androidのアプリケーションを開発しているときに、昨日までは普通にIDE(IntelliJ/IDEA)からUSB接続した実機にアプリケーションをダウンロードして実行できていたのに、今日になって、できなくなってしまった。エラーとして、


Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]
というのがIDEに表示されている。

困ったので色々検索してみると、どうやらWindowsの場合、C:\Users\(ユーザ名)\.androidの下に、debug.keystoreというのが自動的に作成されるらしい。ここに、アプリケーションの署名に必要な証明書が格納されている。Androidでは、たとえデバッグであっても、アプリケーションは署名を付けないといけない。さらに、少なくとも次の場合は、一度インストールしたアプリケーションを再インストールしようとしても、上記メッセージが表示されて失敗する。

  • アプリケーションを異なる証明書で署名した。
  • アプリケーションの署名に使用された証明書の期限が切れた。

自動生成されるdebug.keystoreの証明書には有効期限があり、デフォルトの有効期間は1年間であるようだ。自分の場合、上記の2番目の原因でエラーが発生していた。

いろいろ対処法があるらしいが、とりあえず怠惰なプログラマとしては、もっとも楽な方法を使用した:インストールしたアプリケーションを一度アンインストールし、再度(削除後に再生成されたdebug.keystoreで署名して)インストールする。

ただ、この方法の欠点は、アプリケーションで作成されていたデータもすべて削除されてしまうことである。それが許容できれば、とりあえず一番簡単な対処法であると思う。いずれにせよ、リリースするときには正式に署名を付けるので ...

more…

androidのHttpURLConnection::getInputStreamでjava.io.FileNotFoundException

androidで、HttpURLConnectionクラスを使って、リモートサーバにGETリクエストを送り、結果を取得しようとした。だが、なぜかgetInputStreamを呼び出したところでjava.io.FileNotFoundExceptionが発生する。そのURLをブラウザでアクセスすることはできるのに。

検索してみたところ、いつものStackOverflowに答えがあった。HTTPのレスポンスコードが400以上であると、HttpURLConnectionはFileNotFoundExceptionを投げる、ということが原因だった。ブラウザでアクセスできていると思っていたが、レスポンスコードを見てみると、403 Forbiddenだった。

というわけで、同じ回答では、getResponseCode()を使って問題を特定する、ということが勧められていた。

more…

SQLiteの時刻取得精度について調査した

SQLiteでselect julianday('now')とすると、整数部と小数部からなる値が表示される。これはユリウス日と言われる値になるそうだが、この小数部の精度がどうなっているのか気になったので調査した。

結論からすると、x86アーキテクチャのLinuxで動作している場合、ミリ秒単位が限界となりそうだ。

SQLiteのソースだと、unixCurrentTimeInt64という関数で現在時刻を取得するようだ。この関数のコメントには、


/
Find the current time (in Universal Coordinated Time).  Write into *piNow
the current time and date as a Julian Day number times 86_400_000.  In
other words, write into *piNow the number of milliseconds since the Julian ...

more…

FPGA+HFT

最近モチベーションが下がっている。ネットを徘徊していたら、ちょっと面白いネタを見つけた:

文字通り「ネットワークがコンピューター」な金融HFTでのFPGAの使われ方

ここ数年HFTの分野では、FPGAで処理を実装するのがはやってきている、ということ。リンク先の記事からもリンクされている、Parallel Scientific: The Awesome Haskell FPGA Compilerは以前すこし眺めていたが、今回の記事を読んで全体像の理解が少し進んだ。なるほど、こんなところでも回路設計をしてしまう時代になったのね、という感じ。

10Gbpsのネットワークスイッチに入れてしまうというのであれば、当然Alteraで言えばStratixクラスの1個何十万もするFPGAを使うのだろう。外付けメモリもDDRみたいなレイテンシの大きいものではなく、RLDRAMやQDRといった、個人的には使用しているのをあまり見聞きしないタイプのメモリを使っているのではなかろうか。

もしこういったものがTCP/IPで通信をしているとすれば、Ethernet MACのIPから出てくるパケットをステートマシンでTCP/IP部分をデコードしてやり、中身のデータに基づいてガリガリ計算し、その結果に基づいてこれまたステートマシンでEthernet MAC IPに売買パケットを流し込む、というような流れになっているのだろう。そして売買の結果は、メモリに書き込んでおき、ログとして保存。これでソフトウェアは一切介在せずに株式やら為替の売買を実行する、と。もちろん、売買条件の設定などの初期化操作はソフトウェアで行うはずだが。

妄想するとなかなか面白そうな分野だなぁ。クオンツの元でブイブイ(死語)いわせるプログラマのイメージが。なるほど、金融業界は計算機分野でも ...

more…

OpenCL & GPGPUメモ

さらにOpenCLやGPGPUの実験をしているが、そのメモ。

  •  PCIeを介して、Device to Host, Host to Deviceの双方向転送が同時に実行されない。NVIDIAのGPUだと、Compute Capabilityが1.Xのものだと双方向の同時通信は無理のようなので、AMDもデバイスの制限があるのかも知れない。 これは、複数のコマンドキューを使用して、できるだけコマンドのオーバーラップを試みても、まだ未解決。 カーネルの実行中にデバイスメモリへの転送はできていることは確認できた。
  •  カーネルが使用するメモリを転送し終わってから、実際にカーネルが動作するまでに100ms以上のディレイが発生することがある。clEnqueueNDRangeKernelを呼び出して、直ちにclFlushを実行しているのだが...(このディレイはAMDの場合のみ。NVIDIAではそれほど遅くはない)
  • OpenCLは、単にカーネルを呼び出すにも、カーネル引数をsetKernelArgで一つずつ積み上げなければいけない。しかも、引数のサイズまで指定する必要がある。さらに調査してみたら、GPGPUとしては、C++ AMPという方法もある(ちなみに、リンク先は機械翻訳なので日本語が少し変)らしい。しかも、Visual C++ 2012だと標準で実装されており、をインクルードするだけで使用できる。Microsoftの実装だと、Direct X 11のシェーダとしてカーネルが実行されるようだ。だが、C++ AMPの仕様自体は ...

more…