« 2021年4月 | トップページ | 2021年6月 »

2021.05.28

特電Artix-7ボードでMIPI信号の受信に成功

ハマりまくったけど、ついにRasPi Camera V2からのデータをArtix-7で受信することに成功しました。

こんな配線だけど↓、数百MHzの信号が通ります。

A7mipi

XILINXのコアは、MIPIのHS系の信号だけではなくてLP系の信号もちゃんとつながないとダメなようでした。

また、PとNの入れ替えには対応していません。ほかにもCLKはMRCCかSRCCにつながないとダメなど、制約がかない大きいです。

最初に観測された信号が下記の波形です。

Mipi1_20210716015201

rxclkacvicehsやstopstateといった信号が見えていますね。MIPIの仕様書を読んでいないので想像ですが、LPモードの有効無効でstopstateやactivehsというのを識別しているのだと思います。

rxbyteclkhsは間欠的に出てきます。CLKがHSモードで高速にトグルしているときしか動いていないと思われます。rxbyteclkhsの速度はラインレートの1/8であるようです。

 

FPGA内蔵したロジアナで見ていますが、時間軸を拡大してみると、rxbyteclkhsをCLK200Mで見ているからデューティ比が50%になっていません。rxbyteclkhsはカメラクロックでシステムのクロックとは同期していないためです。

プロトコルを見てみると、rxsynchsが最初に1クロックHになって、その後1Hの期間rxvalidhsがHになるのだと読めます。最初のラインはrxvalidhsが3回出てくるように見えます。(最初の1回はとても短い)

Mipi2_20210716015701

 

何事も同期していないのはよくないので、rxbyteclkhsでサンプリングするようにしてみました。

Mipi3_20210716020001

先頭の2B 54 06 3Eはいつも同じ値になるっぽいです。1ラインは820ピクセルくらいありそうです。ただrxbyteclkhsはバースト的に止まるので内蔵ロジアナのクロックにするには使いにくいといえます。

 

一方、端子をJTAGバウンダリスキャンで見てみると、LPのクロック端子が約35msごとに周期的に動いているのがわかります。

Mipi4_20210716020201

これが1フレームなのでしょう。LPの端子はHUSL12のIO規格ですが、HSモードで動いているときにはLとして認識されるのだと思われます。

 

最後に、うまくいったデザインでのIPの設定とBlockDesignを示します。

Mipi5

Mipi6

 

 

 

 

 

| | コメント (0)

2021.05.26

MIPI CSI-2のRXでうまくいかない

Vivado 2020.2をインストールしてMIPI CSI-2のカメラ受信をしようとしているのですが、なかなかうまくいきません。

XILINXが提供しているコアにはMIPI CSI-2 RX Subsystemというのと、MIPI D-PHYというものの2つがあります。MIPI D-PHYはPHYのみですが、MIPI CSI-2 RX SubsystemはPHYの後ろにタイミング関係やRAW10などのパターンの変換などが付いていてVideoという例のバスが出てくる高度なものになっています。

MIPI CSI-2 RX Subsystemは、MIPI D-PHYにデコーダ回路を付けたものらしいので、まずは高レベルのRX Subsystemで試してみました。

これらのコアを使用して配置配線をするとBitGenやPlaterでエラーが出てしまいます。MIPIのコア自体にはIOSTANDARDの設定がされていないようなので、XDCファイルに

set_property IOSTANDARD LVDS_25 [get_ports cam_clkp_ip]
set_property IOSTANDARD LVDS_25 [get_ports cam_clkn_ip]
set_property IOSTANDARD LVDS_25 [get_ports {cam_dp_ip[0]}]
set_property IOSTANDARD LVDS_25 [get_ports {cam_dn_ip[0]}]
set_property IOSTANDARD LVDS_25 [get_ports {cam_dp_ip[1]}]
set_property IOSTANDARD LVDS_25 [get_ports {cam_dn_ip[1]}]

のように書いてIO規格を指定しなければなりませんでした。

データを受信するI/Oの規格はLVDSなのですが、IO電圧は3.3Vなので、このままだとエラーが出てしまいます。LVDS_25は受信だけなら3.3VのIOでもできるのですが、終端抵抗(DIFF_TERM)が入っているとIO電源電圧は2.5V要求されます。そこで、

set_property DIFF_TERM false [get_ports cam_clkp_ip]
set_property DIFF_TERM false [get_ports cam_clkn_ip]
set_property DIFF_TERM false [get_ports {cam_dp_ip[0]}]
set_property DIFF_TERM false [get_ports {cam_dn_ip[0]}]
set_property DIFF_TERM false [get_ports {cam_dp_ip[1]}]
set_property DIFF_TERM false [get_ports {cam_dn_ip[1]}]

のようにしてDIFF_TERMを無効にして、そのかわりに基板上にチップ抵抗を実装して

 

さて、MIPI CSI-2 RX Subsystemから出てくる信号をロジアナで観測したものの、すべての信号が全く出てきません。

Mipi1

唯一変化があったのは、rxbyteclkhsと、system_rst_outのみです。

rxbyteclkhsはだいたい69MHzくらいなのですがバースト的に動作しています。つまり、動いているときと止まっているときがあります。連続して送られてくるわけではないので、これをPLLの元にすることはできないでしょう。

 

信号が出てこない原因として考えられるのは2つあって、一つはMIPIのLPのほうをつないでいないということ。もう一つは基板の設計を間違えていてMIPIの差動信号のPとNが逆になっていることです。どうやらXILINXのコアにはレーンリバーサルの機能はないようです。

 

高度なRX Subsystemがだめなら低レベルのD-PHYだ、と思って、D-PHYをつないで全信号を内蔵ロジアナで見てみたのですが、

Mipi2

これもダメでした。

Mipi3

全信号がうんともすんとも言いません。

IPの設定はこんな感じです。

Mipi4

さて、次の手はどうしようかと悩むところです。

Trenz社製のMIPI RXコアを使うか、配線のPとNを入れ替えてみるか、どちらかですね。

 

| | コメント (0)

2021.05.25

Trenz社製品の情報をデータベースに入れて在庫と納期を検索できるようにした

TrenzElectronic社のWebショップの在庫を検索して、現在の在庫数、おおよその納期、世代交代前の型番、後継機種の型番を一括で表示するプログラムを作りました。

Trenz社のWebサイトは重いのでひとつひとつのページを見るだけで時間がかかるのですが、実は、特電では3年以上前からTrenz社の製品情報を毎日自動的にクロールして、在庫数や納期などの情報を取得して、独自のデータベースに入れていました。

このデータベースをもとに高速に検索して、現在の在庫数などを表示できるようにしました。

例えば、TE0712という製品の在庫情報が知りたいというときには、zaikocheck.phpというプログラムを走らせると、

Trenzsearch1

というふうに、「TE0712」という文字列を含む製品すべての在庫と、予定納期、それから製品の新旧型番が一瞬でわかるようになりました。

Gigazee 「TE0720」という大ベストセラーな産業用FPGAモジュールのファミリがあるのですが、これは供給が追い付いていないので、現時点で在庫が全くありません。ですが、TE0720で検索すると、

Trenzsearch2

と、次回製造のロットで納期が早いものは、TE0720-03-2IFC3、TE0720-03-62I33FL、TE0720-03-62I33FAあたりだなということが分かります。

 

また、TrenzElectronic社のFPGAボード製品は、最近の改版によって名前が不規則に変化しています。

例えば、TE0720-03-2IFC3はTE0720-03-62I33FLに変わったのですが、旧製品の型番に含まれる-03は基板のリビジョンで、2IFC3は2Iがスピードと温度グレード、C3はコネクタが短いもの、という意味です。しかし、62I33FLになって、さっぱり意味が分からなくなりました。6はおそらくFPGAのサイズ、2Iが温度とスピード、33Fは不明。

型番の意味はわからないのですが、データベースを検索して製品型番のチェーンを自動的に調べるツールを作りました。TE0720についての型番の変化を調べてみると、

TE0720-03-14S-1C     => TE0720-03-31C33FA
TE0720-03-1CF => TE0720-03-1CFA => TE0720-03-61C33FA
TE0720-03-1CF-S => TE0720-03-1CFA-S => TE0720-03-61C33FAS
TE0720-02-1CR => TE0720-03-1CR => TE0720-03-61C530A
TE0720-02-1QF => TE0720-03-1QF => TE0720-03-61Q33FA
TE0720-03-1QFA => TE0720-03-61Q33FA
TE0720-02-1QF => TE0720-03-1QFL => TE0720-03-61Q33FL
TE0720-02-2IF => TE0720-03-2IF => TE0720-03-62I33FA
TE0720-03-2IFA => TE0720-03-62I33FA
TE0720-02-2IFC3 => TE0720-03-2IFC3 => TE0720-03-62I33FL
TE0720-03-2IFC8 => TE0720-03-62I12GA => TE0720-03-62I33GA
TE0720-03-L1IF => TE0720-03-64I63FA
TE0720-02-L1IF => TE0720-03-L1IF => TE0720-03-64I63FA

と、なりました。

このツールはWebサイトに組み込んだので、Trenz製品の一覧と、型番の変化を知りたい場合は

trenz.jp/chain.php

のページを見てみてください。

| | コメント (0)

2021.05.24

Trenz社の全FPGAボード製品のデータを掲載しました

特殊電子回路ではドイツTrenzElectronic社の代理店を行っていて、日本語での製品紹介サイトを作成しています。

Trenz社では2020年ごろからTE07xxおよびTE08xx製品のアップグレードが始まって、TE0720-03-61C33FAなど、新しい型番の製品への移行が始まりました。

しかし、これらの新しい型番の製品の登録が遅れていてたため、日本語サイト内に製品情報がない状態が続いておりましたが、本日すべての型番の登録を行い、当サイト内で製品情報を参照することができるようになりました。

大ベストセラーであるGigazeeファミリの製品情報はもちろん完全に登録しました。

Te07200361c33fa

 

製品情報を見てみると、いつのまにかRFSoCの新製品や

Rfsoc

CRという新しいモータコントローラのシリーズや、

Cr00140

この時期に製品がものすごく増えています。

全部で450アイテムくらいありそうです。すごい開発力です。

 

| | コメント (0)

2021.05.23

XILINXのPCIe 7x 1.9コアでクラッシュする

2016年ごろに作ったPCI ExperssのボードのFPGAのデザインが、SuperMicroというメーカーのマザーボードを使った特定のPCでクラッシュするという現象がお客様から報告されました。

 

この状況を再現するため、特電の倉庫にSuperMicroのマザーを積んだデスクトップPCを取りに行って、CERN CentOS 7という謎ディストリビューションのLinuxをインストールし(インストール中にいろいろダウンロードするので1日以上かかった)たりしていました。

 

調べてみると、BAR0などのメモリ空間にアクセスしつつ、別のシェルでlspciを実行するとハングアップするという感じでした。

落ちる前にはBARからの読み出しでFFFFFFFFが返って来るので、感触としてはBARにアクセスするトランザクションがcompletionを返す前にコンフィグリクエストが来ると、どちらかのcompletionを忘れてしまうんじゃないかと思える挙動です。

 

使っているXILINXIPコアは2016年ごろのpcie 7x 1.9)です。当時のツールはISE14.7かVivado 2016かという選択でしたが、Vivado 2016は使う気にならなかったので、ISEを使っていました。

Ise

そのため、ISE 14.7に入っていたpcie 7x 1.9コアを使っていたのですが、pcie 7x 1.9はPCI Expressのトランザクション層のほぼ生のパケットが出てくるので、PCI Expressをしばらく触っていないと信号の意味を忘れてしまいます。ISEなので膨大な量の信号がテキストベースでインタフェースされているので、どこがどうつながっているのかを把握するだけでも一苦労です。

 

そう考えるとVivadoってすごいですね。配線がどこがどうつながっているか視覚的にわかります。それになんといっても、

・・・
-- Management Interface
cfg_mgmt_di : in std_logic_vector (31 downto 0);
cfg_mgmt_byte_en : in std_logic_vector (3 downto 0);
cfg_mgmt_dwaddr : in std_logic_vector (9 downto 0);
cfg_mgmt_wr_en : in std_logic;
cfg_mgmt_rd_en : in std_logic;
cfg_mgmt_wr_readonly : in std_logic;
-- Error Reporting Interface
cfg_err_ecrc : in std_logic;
cfg_err_ur : in std_logic;
cfg_err_cpl_timeout : in std_logic;
cfg_err_cpl_unexpect : in std_logic;
cfg_err_cpl_abort : in std_logic;
cfg_err_posted : in std_logic;
・・・ 

みたいな100個以上ある謎の信号を扱わなくていいのですから。

Vivado 2019.2に入っている比較的新しいコア(XDMA 4.1)Vivado 2019.2で作ったサンプルデザインで試したところ、全くハングアップしなくなりました。

Xdma

 

なお、XDMA 4.1は中心にpcie 7x 3.3が入っていて、AXIラッパとDMA回路が入ったものです。

pcie 7x 1.9コア が悪いのか、pcie 7xの周辺回路が悪いのかわかりません。pcie 7xの入出力信号を追いかけるのはとても時間がかかる作業となるので原因究明は行いません。まぁ、おそらく未処理のMemRdコンプリーションとCfgRdが重なるとバグるのでしょう。

 

とにかく、新しいVivadoで再設計するのが最も近道のようです。

 

| | コメント (0)

2021.05.19

RasPi Camera V2とFPGAをつないで何らかの信号が出ることを確認

Raspberry Pi Camera V2 (imx219) と特電Artix-7ボードを接続し、I2Cでカメラレジスタを設定してみました。

Raspicam3

I2Cのシーケンスは、Trenz社のZynqberryにおけるRasPiカメラコントロールプログラムrpicamに含まれているsensor_config.hのI2Cシーケンスから調べて、ステートマシンで作ったI2Cコントローラから送り出しています。

Raspicam2

 

すべてのI2C書き込みを終えると、MIPI CSIから何か信号が出てくることが確認できました。

Raspicam1

MITOUJTAGのバウンダリスキャンでI/Oの端子の信号を見ているので、FPGAの中にはロジアナのコアなどを埋め込まなくてもすぐに見られるのがとても楽です。手をかざしてみたりすると密度が少し変化するのが見えます。

| | コメント (0)

2021.05.17

Raspi CameraのI2Cから読み出し

RasPiカメラV2をFPGAで扱うため、まずはI2CのコントロールロジックをVHDLで開発しています。

どうせならちゃんとしたコアを作ろうと思い、NACKリトライまで付けています。

3層のステートマシンが階層間でREQやACKを渡して、精巧な歯車のように連携して動作するコアです。

一番最下層のステートマシン「state_l」は、Start ConditionやStop Condition、Tx、Rxなどの処理を行います。

中間のステートマシン「state_m」は、state_lに指示を出してReadやWriteといったシーケンスを行います。

上位のステートマシン「state_h」は、書き込みたいアドレスとデータのシーケンスをROMから取ってきてstate_mに指示を出します。

このくらいの規模の回路だとHLSやソフトウェアを使うよりRTLの方が楽ですね。

まず、シミュレーションでちゃんと意図したように動いているのを確認します。

I2c_sim

 

実機でやってみると、何かおかしい。

I2CのReadのときにはStart→Devアドレス送信→サブアドレス送信→Start→Devアドレス送信→受信→Stopというのを行うのですが、FPGAが受信するときにNACKで返さないとI2CのターゲットがStopを受け付けずに次のを送ってくるなどして少しハマりました。

無事、RasPiカメラV2のI2CからのACKが確認できて、MODEL_IDが0x02 0x19と正しく読めるようになりました。

Raspicam4

ターゲットから返って来る波形を目でみて確認しているのですが、I2Cのクロックを100Hzくらいまで落とせば、ILAとか入れなくてもMITOUJTAGのバウンダリスキャンでI/Oの波形が見えます。

デバッグ回路をわざわざ入れる必要がなく、すぐに確認できるのが便利です。

| | コメント (0)

2021.05.14

Artix-7ボード用のHDMI&MIPI拡張基板を動かす

特電Artix-7ボード用に作ったHDMI&MIPI拡張基板というのがあります。

Np10881

数年前に開発した基板なのですが、FPGAのサンプルデザインを用意していなかったので、この機会にうごかしつつサンプルデザインを整備しようと思いました。

このようにArtix-7ボードとぴったり重なって、HDMIの入出力や、MIPI CSIカメラをつなげるこことができるというボードです。

Np10882

昔作ったKintex-7用のHDMI出力回路をもとにArtix-7用のHDMI出力を作ろうとしていたのですが、

Hdmiout1

XILINX IPのVideo Outがunderflowを起こして信号が出てきません。

Hdmiout2

これは帯域が足りない場合です。

DDR3の内容をHDMIに表示するような場合、DDR3のMIGから出てくるクロックをベースにAXIを動かしますが、クロック400MHz(DDR800)で動かした場合、デフォルトの4:1の設定ならばui_clkは100MHzで出てきます。

HDMI 1080pは148.5MHzで32bit(xRGB)のバス帯域が必要なので、VDMAの出力のAXI Streamが100MHz 32biのバスだと足りないのです。なので、ui_clkの設定を2:1にして200MHzで出すようにします。

XILINXのVideo IPはわかりにくいのですが、何度もハマるとだんだんコツがわかってきます。

出来上がった回路はこのような感じになりました。

Hdmiout3

USB3.0を通じてDDR3メモリに書き込んだデータをHDMIから出力できるようになりました。

Np10883

| | コメント (0)

2021.05.11

14bit ADCのノイズのヒストグラム

ADCの無信号時のヒストグラム表示時に、標準偏差から求めたガウシアン曲線を同時に表示できるようにしました。

14bitのADCの生データは、12bitの場合よりも大きくなります。

Noise_14bit

このヒストグラムを取ってみると、だいたい±2~3本くらいかなという感じになります。

Hist14bit

リアルタイムに平均と標準偏差を計算し、滑らかなグラフを同時に表示できるようにしてみました。

Hist14bit_2

ノイズのヒストグラムはだいたい正規分布になっているのですが、少し左に寄ったり右に寄ったりするのは、ADCのINLやDNLというやつなのでしょう。出やすい値、出にくい値というのがあるのです。

標準偏差は1.99~2.4LSBと幅があるのですが、なぜでしょうね。

今回のADCは14bitなので1LSB=61μVです。よってADCの計測した値の誤差はチャネルによっても異なりますが、間を取って2.2LSBとすればだいたい±0.13mVといえます。

なんと!

12bitのADCの場合も誤差は0.13mVだったので、ビット数が増えても誤差は変わっていないのです。

 

| | コメント (0)

2021.05.10

高速ADCのヒストグラムと標準偏差

高速なADCや、ビット数の多いADCでは、ADCの入力に何も入れなくても(GNDに接続していても)、変換値は止まらずに常に揺れ動いています。この揺れ、つまりノイズの標準偏差を計算できるようにプログラムを改良してみました。

使用しているADCは、Analog DevicesのAD9633、使用したボードはCosmo-Zです。

 

まず、無信号時の波形というのはこんな感じです。常に揺れていますね。

Nosig_20210512033401

このヒストグラムを取ってみると、

Hist1_20210512033601

このように中心から1~2LSB広がったヒストグラムとなります。

1LSB=244μVなので、このADCは誤差0.244mVで測定できるということになりますが、1~2本という人間の目の感覚は正確ではないので、単純ではありますが平均値、標準偏差を計算して表示してみることにしました。

Hist1

実行結果は#stddevと書かれた行に出ていて、平均値は2048.83、標準偏差は0.55となっています。

つまり、計測値は標準偏差0.55(LSB)=±0.13mV程度の誤差があると言えるでしょう。

 

で、このヒストグラムが本当にガウシアンの形をしているのかどうかを確かめるために、Excelに入れてグラフ化してみました。

ヒストグラム自体は2049を中心として±1くらいのひろがりを持っていますが、

Hist3

y=ピーク値×exp{-(x-平均)^2/標準偏差^2}のグラフを描いて同時に表示させてみると、

Hist2

なかなかいい感じになりました。(オレンジの点が測定値。青の線が計算したガウシアン)

ADCの無信号時のヒストグラムは正規分布に近いといえるでしょう。

 

| | コメント (0)

2021.05.09

マイクロソフトの署名を施したSpartan-7ボードドライバをリリース

マイクロソフトの署名を施したSpartan-7ボード用のUSBデバイスドライバをリリースしました。ようやくWindows10でセキュアブートを入れたまま、テストモードにせずに動くドライバのリリースができました。

Sp7_20210511010301

ドライバはこちらのページにございます。

https://www.tokudenkairo.co.jp/sp7/download.html

 

このドライバはごく初期のEZ-USB FX2用のezusb.sysを64bitに拡張してオブジェクト名などを変えただけのものなのですが、Windows10でも問題なく動くし、マイクロソフトでの検証もパスしています。

気になる通信速度ですが、IN方向で約30MB/sec、OUT方向で約40MB/sec出ています。

Sp7_test

| | コメント (0)

2021.05.08

Windowsのデバイスドライバをマイクロソフトに送って署名してもらう方法

Windowsのデバイスドライバは署名がないとインストールされないのはよく知られていると思います。

Windows XPや7の頃はカーネルモードの署名を施せばインストールすることができましたが、いつからかEV証明書というのが必要になり(証明書の値段が2倍近くになった)、2016年ごろのWindows 10 Anniversal UpdateからEV証明書でもダメになって、マイクロソフトに署名してもらうことが必須になりました。

2020年のこの記事や、2017年のこの記事でも書いたとおり、自分で作ったドライバをマイクロソフトの署名なしに動かすには、

① Windows10がAnniversary Update以前のものからアップデートされている
② PCでセキュアブートを無効にしている
③ 証明書が2015年7月29日以前に発行されている
④ ドライバがOS起動時にロードされる(一時的な措置であり、将来無効になるかも)

のどれかが必要でした。

なお、特電で販売しているSpartan-6ボードは2009年からあるし、Artix-7ボードも2011年ごろからあるので、上の③の条件を満たしているから動くのですが、新しいドライバが作れなくなってしまいます。なお、④の方法はうまくいきませんでした。私は③の方法で古い製品のVID、PIDを使い続けて、古いドライバを使うのがよいと思っているのですが・・

そのため、自作のデバイスドライバを動かすため「セキュアブートを無効にしてください」というようなお願いをしているハードウェアメーカーも少なからずあります。 

そろそろマイクロソフトに認証してもらうことからは逃げられなくなってきたのですが、気になるポイントは2つあります。

● ドライバに厳しいテストをしなければいけないのか?

● 追加の費用が発生するのか?

このあたりが気になるところです。

そういうわけで、マイクロソフトに送って署名を施してもらう方法を調べてみました。

やり方はここここに書いてあるのですが、ざっくり言うと、

  • EVコードサイニング証明書を取得する(SSLのEV証明書とは別) ※追記
  • 「マイクロソフトのハードウェアパートナープログラム」に登録する。
  • 署名を施したものをCABでアーカイブする
  • ハードウェアパートナープログラムのWebから送信する

というもので、意外とあっけないものでした。

手順通りにやったら、本当にあっけなく、ドライバがインストールされて動作しました。

Driver

今までの心配はなんだったんだろう。。

 

それでは手順を説明します。まずEVコードサイニング証明書をGMOグローバルサインとかで購入してください。 ※追記

それから、Azure Active Directoryへの登録を行います。Azure Active Directoryというのはユーザ名@会社名.onmicrosoft.comのメールアドレスが発行されるアレです。

1_20210509003701

この登録フォームで会社名を入れていくと、唐突に「コード署名証明書」を要求されます。

2_20210509003701

このページからbinファイルをダウンロードして、signtoolを使って署名を施します。

3_20210509003701

署名を施したbinファイルをサイトにアップロードすると先に進めるようになります。

4_20210509003901

EV証明書を持っていないと先に進めません。厳しいですが、EV証明書は会社が存在していれば簡単に取得できるので、そんなに難しい話ではありません。ツイッタランドにのみ存在する架空の会社ではドライバが作れないのでご注意ください。

 

登録が済むと、Microsoftパートナーセンタのハードウェアダッシュボードが開きます。

いろいろな試行錯誤をした後なのでごちゃごちゃとあります(不要なプロジェクトが消せない)。

Partner_center

Submit New Hardwareをクリックします。

New_hardware

ハードウェアの名前を入力して、灰色の部分にINFとSYSとCATを固めたCABファイルをドラッグアンドドロップします。

簡単に説明すると、デバイスドライバの本体はSYSファイルで、それをインストールするためのファイルがINFファイルです。INFを書いたらinf2catでCATファイルに変換して、signtoolでCATとSYSに署名をします。コインストーラのDLLとかがある場合は一緒に固めます。ここまでは従来のデバイスドライバの開発と同じです。

異なる点は、INF,CAT,SYSをどこかのディレクトリに入れて、DDFファイルを書いてCABを作ることです。

;**_ Echo.ddf example
;
.OPTION EXPLICIT ; Generate errors
.Set CabinetFileCountThreshold=0
.Set FolderFileCountThreshold=0
.Set FolderSizeThreshold=0
.Set MaxCabinetSize=0
.Set MaxDiskFileCount=0
.Set MaxDiskSize=0
.Set CompressionType=MSZIP
.Set Cabinet=on
.Set Compress=on
;Specify file name for new cab file
.Set CabinetNameTemplate=tkdnsp6x64.cab
; Specify the subdirectory for the files.
; Your cab file should not have files at the root level,
; and each driver package must be in a separate subfolder.
.Set DestinationDir=win10x64
;Specify files to be included in cab file
D:\naitou\np1116\np1116fw\win10driver\win10x64\tkdnsp6x64.cat
D:\naitou\np1116\np1116fw\win10driver\win10x64\tkdnsp6x64.sys
D:\naitou\np1116\np1116fw\win10driver\win10x64\tkdnsp6x64.inf

こういうファイルを作っておいて、

makecab /f tkdnsp6x64.ddf

とすれば、指定されたファイルがCABに固められます。普段はCABで圧縮することなんてないので、こんなファイルを作る機会はめったにないと思います。署名してディレクトリ作ってコピーしてCABで固めるという作業は何度も試行錯誤すると思うのでバッチファイルを作ったほうがいいでしょう。

その次に、どんなハードウェアをサポートするかというチェックボックスがあるので、x64と書いたものを全部チェックしておきます。

15_20210509010101

これでSubmitを押せば提出完了です。

マイクロソフトのサーバの中で検証が行われ、画面が自動的に更新されていきます。

最初のPreparationでINFファイルのエラーが徹底的に検証されます。おそらく、最初は何度もエラーが出て拒否されるのではないかと思います。

16_20210509010201

そのたびにINFを直して再度CABを作ってEV署名して、新たなプロジェクトを申請して、という試行錯誤を繰り返します。

エラーがなければ、Scanning、Validation、Catalog creation、Sign、Finalizeのすべてのプロセスが15分くらいで完了します。

そうしたら名前の右にあるMoreをクリックして、下の図にあるDownload signed filesを出し、これを押します。

Complete

これで、マイクロソフトに署名されたドライバがダウンロードできるというわけです。

Signed_driver

このドライバをインストールすれば最新のWindows 10で、セキュアブートを有効にしたまま動かすことができます。

めでたしめでたし。

 

ちょっと、署名の中身を見比べてみましょう。

ドライバのCATファイルのプロパティから、デジタル署名のタブを開いてみます。

自分でEV署名を行った状態では、署名者名が自分になっています。

Original

マイクロソフトに提出したものをダウンロードしたドライバでは、署名者名がMicrosoft Windows Hardware Compatibility Publisherに変わっています。おおー

Signed

また、拡張キー使用方法というところが「コード署名 (1.3.6.1.5.5.7.3.3)」だけだったのが、

Original2

「Windows ハードウェア ドライバーの確認 (1.3.6.1.4.1.311.10.3.5) Windows ハードウェア ドライバーの構成証明付き検証 (1.3.6.1.4.1.311.10.3.5.1) コード署名 (1.3.6.1.5.5.7.3.3)」に増えています。

Signed2

なんだかよくわからんが、強そうだ。

 

あと、署名が完了したら、パートナーセンターのNew Shipping Labelというところを押せば、Windows Updateを通じて配布できるようになるらしいです。つまり、「USBでつないだら自動的にWindows Updateからドライバがダウンロードされてインストール」ができるようになるのですが、どのようなテストをしたかとか、協力しているマイクロソフトスポンサーのメールアドレスとか書かなければならないようなので、ちょっとハードルが高いですね。

自分のサイトでのみ配布することにしておけば、ここまでで十分です。

そういえば、ドライバに厳しいテストをする場面やテストレポートの提出はありませんでした。また、費用も発生しませんでした。

想像していたような怖いものではなかったので、デバイスドライバを開発した人はぜひチャレンジしてみてください。

| | コメント (2)

2021.05.03

Cosmo-Zの操作アプリをWindowsに移植中

これまでZYNQ Linuxで動作していたCosmo-Zを操作するアプリ「cszmain.elf」をWindowsに移植中です。

Cszwin

苦労しているのは、string.hの関数の扱いです。

なぜだかわかりませんが、Linuxでは大文字小文字を気にしない文字列比較がstrcasecmpなのに、Windowsではstricmpになります。Visual C++だけでなくBorland C++でもstricmpなのでなぜなんでしょうね。

他にも、Visual C++だとstrcatとか使えなくてstrcat_sになっていたり、strdupは_strdupになっていたりするので一つ一つ置き換えていきます。

ディレクトリの中のファイル一覧を見る関数とかは全面的に変えなければならないでしょうね。

このような単純な置き換え作業がまだまだ続きます。

 

| | コメント (1)

2021.05.02

Cosmo-Zの波形キャプチャプログラムをWindowsに移植

Cosmo-Zの波形キャプチャプログラムcsz_captureを、Windowsに移植できました。

昨日得られた知見どおり、TCP/IPのパケットをwrite-read-write-read-・・・とすることで、レスポンスが劇的に改善されました。同一LAN内であればネットワーク越しに操作していることを感じさせない応答性の良さです。

Capture

ZYNQのPLに置いたレジスタへの書き込みや、ZYNQのメモリの物理アドレスを指定したアクセスというローレベルな動作をTCP/IP越しに行えるようにしているので、セキュリティ的なことを考えれば、パスワードによる保護とかいろいろしなければならないんでしょうね。

 

| | コメント (0)

2021.05.01

PCとZYNQ Linux間のTCP/IP通信プログラム(2)

このようなアーキテクチャになると、TCP/IP越しに行われる操作はレジスタリードやレジスタライトといったプリミティブな操作なので、プロトコル的には、

Cosmozapi3

こんなやりとりを何度も何度も繰り返すわけです。1回の計測で数十回の操作が生じるとは思うのですが、細かいパケットをどのくらいの速さで投げ合えるかということがレスポンスを左右するポイントになります。

 

単純に実験してみた感じでは16バイト小分けにしてsend()関数を呼んでも、実際に送出されるときには複数個まとめられて1500バイトくらいのパケットになってしまってよくわからないので、

int yes = 1;
setsockopt(sock, SOL_TCP, TCP_NODELAY, &yes, sizeof(yes));

とやってNagelのアルゴリズムがOFFになって1個1個のパケットで出ていくかと思ってやってみたのですが、少しはバラけたものの完全に1個1個分離されることはありませんでした。

 

サーバ側でrecvしておいて何かのコマンドを受け取ったらsendで返す。クライアント側ではsendして、recvで何かを受信したら次にsendをする、というプログラムを組んで実験してみました。

その結果、

Cosmozapi4

TCP dumpで見てみると、だいたい1ミリ秒で1.5~2往復くらい出来ているようです。つまり毎秒1500~2000回のレジスタリード/ライトができるようです。

もちろん地球の裏にあるようなCosmoZを操作するなら重くなるかもしれませんが、同一ネットワーク内にあるZynq Linuxを操作するなら十分な速度が出ているといえます。

 

あと、send関数などのmanか何かで読んだのですが、write-write-readのプロトコルを作るのは推奨されないとのことでした。TCP/IPの送信制御タイミングの問題で待ち時間が生じるようです。

レジスタライトのようにレスポンスがいらない操作の場合にまさにこの状況が発生します。レジスタライトだと、PCからZYNQへアドレスとデータをパケットを送るだけでよく応答を見る必要はないのですが、その後にレジスタリードを行うとwrite-write-readになってしまいます。これをするとものすごく遅くなります。30回の操作で1秒くらいの待ち時間が生じていたような気がします。レジスタライトに0000とかダミーの応答を返すようにしたら驚くほど速くなりました。

こういったAPIやプロトコルを設計する場合は、応答が必要のないコマンドでも何らかの応答を返すようにしないといけないようですね。

 

| | コメント (0)

« 2021年4月 | トップページ | 2021年6月 »