« 2017年7月 | トップページ | 2017年9月 »

2017.08.31

JESD204BのデータをPCIe-DMAで受け取る

高速ADCコンバータから送られてくるJESD204Bの信号を、Kintex-7でデコードして、それをPCI Expressで受け取るサンプルデザインができました。うちのアルバイトさんが全部作ってくれました。

使っているADCボードは1Gsps 16bit 2chのHyperFADC 、PCI Experssボードは40Gbps光モジュールのついたCosmo-K+ です。

Hyadc1

デザインの全体は下の図のようになっています。PCI ExpressのブロックとJESD204BのブロックがBlockMemoryを共有してデータをやり取りする構成になっています。

Jesd1

PCIe BlockにはXDMAコアが入っていて、ホストPCからの指令によってAXIのバースト転送を発生させるようになっています。

Jesd2

JESDのブロックには、JESD204BのPHY、JESD→AXI Streamの変換コア、MicroBlaze、AXI DMAなどが入っています。

XILINXのJESDのコアは有料版ならばAXI出力ができるらしいのですが、無料版はPHYのみしかないようです。そこで、JESDのPHYのみXILINXのコアを使って、AXI Streamへの変換は自作しました。

JESD PHYの設定はこのようになっています。HyperFADCは10Gbps×4本で信号を出力してきますが、信号の受信は2.5Gbpsなので、送信は2.5G、受信は10Gと非対称な構成になっています。

Jesd4

MicroBlazeが入っている理由は、JESD204BをAXI Streamに変換した後、それをAXI MemoryMapに変換する「AXI DMA」の設定のためです。

MicroBlazeを入れるのはオーバースペックではないかと思ったのですが、AXI DMAは意外と設定することが多いので、ハードウェアのロジックでAXI Liteのトランザクションを発行して設定するよりも、MicroBlazeを入れてしまったほうが楽だそうです。

それに、ヒストグラムが乱れたら高速ADCにリセットをかけるなどというインテリジェントな動作もできます。

AXI DMAは、AXI StreamをMemoryMapに変換します。設定を次の図に示します。

Jesd5

こうして、JESD204Bで受信したデータを、AXI Stream→AXI MM→BlockRAMへと格納し、PCI ExpressからXDMAを使って読み出すデザインが出来上がりました。

| | コメント (0)

2017.08.30

Windows10でWindows7用のデバイスドライバを開発する

先日書いたWindows10時代のデバイスドライバ開発とデバッグの記事にしたがって作ったデバイスドライバは、Windows7や8で動かないようです。

おそらく、最新のWDKを入れているので、Windows8用のライブラリなどがないためでしょう。

試しに、VisualStudioのプロジェクトのプロパティでプラットフォームに8.1を選択してみたものの、wdm.hがないとか、いろいろなエラーが出ます。

やはり8.1対応のSDKやWDKをいれないといけないようです。

Win7_driver_dev1

そこで、昔のマシンを使ってWindows7時代のWDKを使ってビルドしてみました。同じソースなのですが、なぜかCではなくCPPにしないとうまくコンパイルできないとか困ったことはありましたが、とりあえずビルドはできて、署名を施したらWindows8のマシンにインストールできました。

Drv_win7_2_2Drv_win7_3

Windows10マシンでDMAの速度を測ってみると、Windows7用に作った速度は1600MB/s程度。

Drv_win7

WDK10でWindows10用に作ったドライバも速度も1600MB/st程度で、全く差はありませんでした。

Drv_win10

| | コメント (0)

2017.08.29

祝!MITOUJTAG BASIC出荷1000台

MITOUJTAGは、2003年度の未踏ソフト創造事業で採択されて開発をスタートしたJTAGソフトウェアですが、期間後も開発を続けて14年。ついに、MITOUJTAG BASICの出荷が1000本に達しました。(MITOUJTAG ProとLightを入れれば1000数百台になります。)

Mjb1

Mjb2

1000台に達するまでいろいろなことがありましたが、これもひとえに、購入してくれたお客様のおかげです。

これからもGUI版バウンダリスキャンの先駆けとして頑張りますので、今後ともよろしくお願いします。

Brd_sp3a_13

| | コメント (0)

2017.08.28

特電のホームページが新しくなりました

特殊電子回路株式会社のホームページを全面的にリニューアルし、本日から移行しました。

トップに大きな画像とマンションポエムが流れるようにしました。

Tokuden_web_1

新しくなったホームページへぜひお越しください。

http://www.tokudenkairo.co.jp/

| | コメント (0)

2017.08.26

GlobalSignの関連する証明書

今回のカーネルモード署名に関連する証明書は以下のようなものがあるようです。

Globalsign Root CA .crt

シリアル番号 6129152700000000002a
拇印 cc1deebf6d55c2c9061ba16f10a0bfa6979a4a32

Globalsign Root CA R3.crt

シリアル番号 330000003b6ac01e2b21e615dc00000000003b

拇印 814a5bb5e9093011e121e75169008f6f4667363d

r1cross.cer

シリアル番号 04000000000125071df9af

拇印 4765557af418c68a641199146a7e556aa8242996

GlobalSignからGlobalSign Extended Validation CodeSigning CAへの証明書

シリアル番号 481b6a07a9424c1eaafef3cdf10f

拇印 87a63d9adb627d777836153c680a3dfcf27de90c

どうやら、GlobalSign Root CA.crtやCA R3というのは、Microsoft Code Verification Rootから発行されたもので、GlobalSign Root CAはここによると以下の証明書であるようです。

GlobalSign Root CA(真?)

シリアル番号 040000000001154b5ac394
拇印 b1bc968bd4f49d622aa89a81f2150152a41d829c

ほかに存在している証明書としては

・MicrosoftからGlobalSign Root CA

拇印 CC1DEEBF6D55C2C9061BA16F10A0BFA6979A4A32

GlobalSign Root CA - R3

シリアル番号 04000000000125071df9af
拇印 8ff04b7fa82e4524ae4d50fa639a8bdee2dd1bbc

があるようです。

この結果に基づいて見てみると、昨日のR3ではないほうで署名したものは

・GlobalSign Root CA(真)→r1cross→GlobalSign EV→自分

クロスチェーンは

・Microsoft→GlobalSIgn Root CA→r1cross→GlobalSign EV→自分

証明書多すぎ!

さっぱりわかりません。ルートとなるものがMicrosoftとGlobalSignの2つあって、クロス証明書や中間証明機関で枝分かれすると思うのですが、クロス証明の仕組みを勉強したほうがよさそうです。

| | コメント (0)

2017.08.25

GlobalSignのEV証明書でカーネルモード署名した結果

Cosmo-K用のデバイスドライバを作って署名したものの、インストールしようとするとコード52が出てしまうので、困っていました。

Code52_2

Windows10では通常の署名ではだめでEVコードサイニング証明書が必要だと聞いたので、GlobalSignでEVコードサイニング証明書を購入し、試してみたのですが、結果は同じ。

何度やってもコード52が出てしまいます。

signtool sign /v /ac ".\GlobalSign Root CA R3.crt" /a /n "コモンネーム" /tr http://rfc3161timestamp.globalsign.com/standard /td sha256 tkpe2.cat

グローバルサインにサポートを依頼したところ、以下のような回答が得られました。

① まず、信頼されたルート機関と中間証明機関に、GlobalSign Root CA R3.crtが入っていれば削除する。

② 下記の証明書をダウンロードし、signtool.exeと同じ場所に保存する。http://download.microsoft.com/download/2/4/E/24E730E6-C012-448F-92B6-78744D3B77E1/GlobalSign%20Root%20CA.zip

③ 下記の証明書をダウンロードし、中間証明機関にインストールする。

https://jp.globalsign.com/support/docs/r1cross.cer

④ 下記の署名コマンドを実行する。

signtool sign /v /ac "GlobalSign Root CA.crt" /a /n "コモンネーム" /tr http://rfc3161timestamp.globalsign.com/advanced ファイル名

というものでした。

私は証明書の仕組みについてはよくわからないのですが、GlobalSign Root CA R3ではなくGlobalSign Root CAを使うということのようです。すると、いままでの苦労がうそのようにあっさりとインストールできました。

Cosmokdriver

これでsigntool.exe verify /kp /vでベリファイをしてみると、

Verifying: tkpe2.cat

Signature Index: 0 (Primary Signature)
Hash of file (sha1): 95902E95CD49AE5B8924B4D1AFBBC354E19641DB

Signing Certificate Chain:
    Issued to: GlobalSign Root CA
    Issued by: GlobalSign Root CA
    Expires:   Fri Jan 28 21:00:00 2028
    SHA1 hash: B1BC968BD4F49D622AA89A81F2150152A41D829C

        Issued to: GlobalSign
        Issued by: GlobalSign Root CA
        Expires:   Mon Mar 18 19:00:00 2019
        SHA1 hash: 4765557AF418C68A641199146A7E556AA8242996

            Issued to: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
            Issued by: GlobalSign
            Expires:   Sat Jun 15 09:00:00 2024
            SHA1 hash: 87A63D9ADB627D777836153C680A3DFCF27DE90C

                Issued to: Tokushu Denshi Kairo Inc.
                Issued by: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
                Expires:   Thu Aug 23 11:36:18 2018
                SHA1 hash: 9B7F00E95E323928A14CE6FC9C3AE8AB1A745D68

The signature is timestamped: Fri Aug 25 10:15:52 2017
Timestamp Verified by:
    Issued to: GlobalSign Root CA
    Issued by: GlobalSign Root CA
    Expires:   Fri Jan 28 21:00:00 2028
    SHA1 hash: B1BC968BD4F49D622AA89A81F2150152A41D829C

        Issued to: GlobalSign Timestamping CA - G2
        Issued by: GlobalSign Root CA
        Expires:   Fri Jan 28 21:00:00 2028
        SHA1 hash: C0E49D2D7D90A5CD427F02D9125694D5D6EC5B71

            Issued to: GlobalSign TSA for Standard - G3 - 001-02
            Issued by: GlobalSign Timestamping CA - G2
            Expires:   Fri Jan 28 21:00:00 2028
            SHA1 hash: A930E98F04BFE6ED0C64D76DD2FCE37A95979E02

Cross Certificate Chain:
    Issued to: Microsoft Code Verification Root
    Issued by: Microsoft Code Verification Root
    Expires:   Sat Nov 01 22:54:03 2025
    SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3

        Issued to: GlobalSign Root CA
        Issued by: Microsoft Code Verification Root
        Expires:   Fri Apr 16 05:05:08 2021
        SHA1 hash: CC1DEEBF6D55C2C9061BA16F10A0BFA6979A4A32

            Issued to: GlobalSign
            Issued by: GlobalSign Root CA
            Expires:   Mon Mar 18 19:00:00 2019
            SHA1 hash: 4765557AF418C68A641199146A7E556AA8242996

                Issued to: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
                Issued by: GlobalSign
                Expires:   Sat Jun 15 09:00:00 2024
                SHA1 hash: 87A63D9ADB627D777836153C680A3DFCF27DE90C

                    Issued to: Tokushu Denshi Kairo Inc.
                    Issued by: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
                    Expires:   Thu Aug 23 11:36:18 2018
                    SHA1 hash: 9B7F00E95E323928A14CE6FC9C3AE8AB1A745D68


Successfully verified: tkpe2.cat

Number of files successfully Verified: 1
Number of warnings: 0
Number of errors: 0
↑GlobalSign Root CA(R3ではない)を使って署名。成功する

さて、いままでの環境でGlobalSign Root CA R3を使って署名したものも同様にverifyで検証してみました。これはインストールに失敗しる場合の署名検証結果です。

Verifying: tkpe2.cat

Signature Index: 0 (Primary Signature)
Hash of file (sha1): 95902E95CD49AE5B8924B4D1AFBBC354E19641DB

Signing Certificate Chain:
    Issued to: GlobalSign Root CA
    Issued by: GlobalSign Root CA
    Expires:   Fri Jan 28 21:00:00 2028
    SHA1 hash: B1BC968BD4F49D622AA89A81F2150152A41D829C

        Issued to: GlobalSign
        Issued by: GlobalSign Root CA
        Expires:   Mon Mar 18 19:00:00 2019
        SHA1 hash: 4765557AF418C68A641199146A7E556AA8242996

            Issued to: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
            Issued by: GlobalSign
            Expires:   Sat Jun 15 09:00:00 2024
            SHA1 hash: 87A63D9ADB627D777836153C680A3DFCF27DE90C

                Issued to: Tokushu Denshi Kairo Inc.
                Issued by: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
                Expires:   Thu Aug 23 11:36:18 2018
                SHA1 hash: 9B7F00E95E323928A14CE6FC9C3AE8AB1A745D68

The signature is timestamped: Fri Aug 25 10:13:50 2017
Timestamp Verified by:
    Issued to: GlobalSign Root CA
    Issued by: GlobalSign Root CA
    Expires:   Fri Jan 28 21:00:00 2028
    SHA1 hash: B1BC968BD4F49D622AA89A81F2150152A41D829C

        Issued to: GlobalSign Timestamping CA - G2
        Issued by: GlobalSign Root CA
        Expires:   Fri Jan 28 21:00:00 2028
        SHA1 hash: C0E49D2D7D90A5CD427F02D9125694D5D6EC5B71

            Issued to: GlobalSign TSA for Standard - G3 - 001-02
            Issued by: GlobalSign Timestamping CA - G2
            Expires:   Fri Jan 28 21:00:00 2028
            SHA1 hash: A930E98F04BFE6ED0C64D76DD2FCE37A95979E02

Cross Certificate Chain:
    Issued to: Microsoft Code Verification Root
    Issued by: Microsoft Code Verification Root
    Expires:   Sat Nov 01 22:54:03 2025
    SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3

        Issued to: GlobalSign Root CA
        Issued by: Microsoft Code Verification Root
        Expires:   Fri Apr 16 05:05:08 2021
        SHA1 hash: CC1DEEBF6D55C2C9061BA16F10A0BFA6979A4A32

            Issued to: GlobalSign
            Issued by: GlobalSign Root CA
            Expires:   Mon Mar 18 19:00:00 2019
            SHA1 hash: 4765557AF418C68A641199146A7E556AA8242996

                Issued to: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
                Issued by: GlobalSign
                Expires:   Sat Jun 15 09:00:00 2024
                SHA1 hash: 87A63D9ADB627D777836153C680A3DFCF27DE90C

                    Issued to: Tokushu Denshi Kairo Inc.
                    Issued by: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
                    Expires:   Thu Aug 23 11:36:18 2018
                    SHA1 hash: 9B7F00E95E323928A14CE6FC9C3AE8AB1A745D68


Successfully verified: tkpe2.cat

Number of files successfully Verified: 1
Number of warnings: 0
Number of errors: 0
↑GlobalSign Root CA R3を使って署名した結果。失敗する

次は一度いろいろ削除してからCA R3を使って署名したもの。
なぜか成功しました。

Verifying: tkpe2.cat

Signature Index: 0 (Primary Signature)
Hash of file (sha1): 95902E95CD49AE5B8924B4D1AFBBC354E19641DB

Signing Certificate Chain:
    Issued to: GlobalSign Root CA
    Issued by: GlobalSign Root CA
    Expires:   Fri Jan 28 21:00:00 2028
    SHA1 hash: B1BC968BD4F49D622AA89A81F2150152A41D829C

        Issued to: GlobalSign
        Issued by: GlobalSign Root CA
        Expires:   Mon Mar 18 19:00:00 2019
        SHA1 hash: 4765557AF418C68A641199146A7E556AA8242996

            Issued to: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
            Issued by: GlobalSign
            Expires:   Sat Jun 15 09:00:00 2024
            SHA1 hash: 87A63D9ADB627D777836153C680A3DFCF27DE90C

                Issued to: Tokushu Denshi Kairo Inc.
                Issued by: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
                Expires:   Thu Aug 23 11:36:18 2018
                SHA1 hash: 9B7F00E95E323928A14CE6FC9C3AE8AB1A745D68

The signature is timestamped: Fri Aug 25 10:34:30 2017
Timestamp Verified by:
    Issued to: GlobalSign Root CA
    Issued by: GlobalSign Root CA
    Expires:   Fri Jan 28 21:00:00 2028
    SHA1 hash: B1BC968BD4F49D622AA89A81F2150152A41D829C

        Issued to: GlobalSign Timestamping CA - G2
        Issued by: GlobalSign Root CA
        Expires:   Fri Jan 28 21:00:00 2028
        SHA1 hash: C0E49D2D7D90A5CD427F02D9125694D5D6EC5B71

            Issued to: GlobalSign TSA for Standard - G3 - 001-02
            Issued by: GlobalSign Timestamping CA - G2
            Expires:   Fri Jan 28 21:00:00 2028
            SHA1 hash: A930E98F04BFE6ED0C64D76DD2FCE37A95979E02

Cross Certificate Chain:
    Issued to: Microsoft Code Verification Root
    Issued by: Microsoft Code Verification Root
    Expires:   Sat Nov 01 22:54:03 2025
    SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3

        Issued to: GlobalSign
        Issued by: Microsoft Code Verification Root
        Expires:   Thu Jun 05 02:47:53 2025
        SHA1 hash: 814A5BB5E9093011E121E75169008F6F4667363D

            Issued to: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
            Issued by: GlobalSign
            Expires:   Sat Jun 15 09:00:00 2024
            SHA1 hash: 87A63D9ADB627D777836153C680A3DFCF27DE90C

                Issued to: Tokushu Denshi Kairo Inc.
                Issued by: GlobalSign Extended Validation CodeSigning CA - SHA256 - G3
                Expires:   Thu Aug 23 11:36:18 2018
                SHA1 hash: 9B7F00E95E323928A14CE6FC9C3AE8AB1A745D68


Successfully verified: tkpe2.cat

Number of files successfully Verified: 1
Number of warnings: 0
Number of errors: 

↑GlobalSign Root CA R3を使って署名した結果。成功する

違いは何かと考えてみると、失敗するほうはCross Certificate Chainが

        Issued to: GlobalSign Root CA
        Issued by: Microsoft Code Verification Root
        Expires:   Fri Apr 16 05:05:08 2021
        SHA1 hash: CC1DEEBF6D55C2C9061BA16F10A0BFA6979A4A32

            Issued to: GlobalSign
            Issued by: GlobalSign Root CA
            Expires:   Mon Mar 18 19:00:00 2019
            SHA1 hash: 4765557AF418C68A641199146A7E556AA8242996

を通っている、ということくらいでしょうか。

以上のことをGlobalSignに報告したところ、R3ではなくRoot CAを使って署名してほしいとのことでした。

ただ、PCを変えたり、証明書を削除したりインストールしなおしたりすると、検証に通るものができたり通らなくなったりするので、何か原因なのかはわかりません。

証明書のルート証明機関や中間証明機関のストアに何が入っているか、とかいう微妙な条件で証明のルートが変わってしまって、検証に通る署名ができたりできなかったりするのかもしれません。

| | コメント (0)

2017.08.22

特電の新しいWebサイト

現状の特電のWebサーバは2011年に建てたのですが、いろいろな意味で限界に達しています。

ディスクの残り容量がほとんどないだけではなく、PHPやSSLの機能が古かったり、gitが使えなかったりしていて、いろいろ不便なことが多くなってきました。

根本的に直すにはOSごとアップグレードしなければなっらないのですが、せっかくなので新しいVPSを借りて移行することにしました。その際にWebサイトのデザインも一新することにしました。

Newsite_1

このように、トップページの最初に大きな写真とマンションポエムを出すことにしました。現代風になりました。

それから、特電の様々なジャンルにわたる製品を統一的に扱うため、bootstrap3のタブ機能を使ってカテゴリごとに製品を分類して表示するようにしました。

Newsite_2

Newsite_3

サイトの編集は特電CMSというシステムを使っていて、Webサイト上で編集できるようにしているので非常に楽ちんです。サイトを編集モードにするとリッチなエディタでサイトに書き込みができるようになるというわけです。

Newsite_4

新しいデザインはなかなか洗練されています。

今週中には正式に移行したいですね。

| | コメント (0)

2017.08.18

セキュリティキャンプの講師をしてきました

縁があって、今年はセキュリティキャンプの講師をさせていただくことになりました。

8月14日、キャンプ2日目の1コマ目の講義で、持ち時間は4時間です。

B1

(twitter @security_campに上がっていた写真を掲載)

参加者は10名で、事前学習をやってきてくれた人は半分くらいでした。

事前学習として、「Artyで100Mイーサを出すサンプルのプロジェクトをダウンロードして、論理合成して動かす。さらに、自分で改良して何かの回路を付け加える」という課題を出していたのですが、そこまでできた人は皆無でした。

みんな、VivadoのインストールとサンプルのLEDチカチカはしてくれていたようなので、講義の時間にVivadoの使い方を説明しないで済んだことは幸いでした。Vivadoの使い方やFPGAの使い方を説明したら4時間では足りません。

事前学習のときにサイボウズ掲示板で質問を受けていた「Vivadoでのシミュレーションのやり方」と「AXI Stream」について最初の1時間くらいで説明し、その後、イーサネットコアの説明などをしたらあっという間に3時間くらい立ちました。

その後、みんなで少しずつコードを読んだり、コードをビルドして、Artyからパケットを出したりするなど緩く進めました。

作ったスライドには秘密の情報は入っていないので、記念にアップロードしておきます。

Slide0_2 Slide1

Slide2 Slide3

みんなで100Mのパケットを出し合って、それをWireSharkでキャプチャするというものですが、宛先MACアドレスをFF:FF:FF:FF:FF:FFにしておけばスイッチングハブを超えてすべての人に届きます。(講義室から外には出ない)

半分くらいの人がUDPやPINGを出すことに成功していたようです。

講義の中で10GのARPパケットを連続で出すというのもやりましたが、会場に置かれたハブが1Gなので、10:1にパケットがロスしているのであまり意味はなかったかもしれません。来年以降、会場の基幹ネットワークが10Gにアップグレードされたら、ぜひ、部屋から外に出してみたいですね。

講義参加者にFPGAのプロジェクトを渡し、10Gイーサを出せるボードと、10Gハブを置いてかえって来ました。夜中にだれかやってくれるかと思ったのですが、特に試したという話は聞きませんでした。

3日目と4日目も会場に様子を見に行ったり質問を受けたりしたかったのですが、頭痛でダウンしてしまって、5日目に機材を取りに行くのが精いっぱいでした。

反省点としては、イーサフレームの構造(プリアンプル、MACアドレス、0800とかのタイプ、それからペイロードがあって、最後にFCSが来る)と、ARPパケットの構造とARPの仕組み、UDPの構造などをちゃんと説明しておけばよかったという点です。

いかにして、これをFPGAのステートマシンで作ったり解読したりするかという話なのですが、その説明を端折ってしまったため理解しにくかったかもしれません。

それから、他の講師の皆さんは非常に上手に面白く講義をするので、自分の講義や資料作りのスキルのなさを切に感じました。

キャンプに誘ってくださった方々、事務局の皆様、このIPコアを作ってくれた特電のスタッフ、それから私の講義に申し込んでくれていた受講者の皆様、本当にありがとうございました。

もしまた来年のキャンプに関われることがあったら、来年はJTAGを使ったハックの話をさせていただきたいです。

| | コメント (0)

2017.08.12

PCI Express 64bitでのDMA

PCI ExpressのBARを64bitにして、デバイスドライバで64bitのDmaAdapterをgetすれば、マップレジスタがエミュレーションされないのでデータのコピーが行われず、超高速になるのではないかと思い、実験してみました。

結果は大正解でした。

Speed_64

Read/Writeともに1.6GB/sほど出ています。PCI ExpressのBARが32bitだったときには1.0GB/s程度だったので、約1.6倍に高速化されました。この差は大きいですね。

一つ一つの転送波形を見てみることにします。

まず、DMA WRの波形。

Dmawr_64

拡大してみてみると、256ns転送して32ns休むというサイクルになっています。

Dmawr_64_mag

256/(256+32) * 2GB = 1.7GB

なので、XDMAコアが出すAXIの最高速度はこのくらいです。

また、DMA RD(C2H)の波形ですが、2.4usくらいのサイクルの間に2.1usくらいの転送が行われているので、やはり1.7GBくらいとなります。

Dmard_64

Dmard_64_mag

PCI Expressの先にあるAXIの速度が1.7GBで、Windowsのアプリケーションで測った速度が1.6GBなので、ほぼフルの速度が出ていると考えてよいともいます。

結論をまとめると、

  • PCI Expressを32bit BAR構成にすると、スキャッタギャザーDMAを実現するときにHALでデータコピーが発生するので遅くなる。約1.0GB/secしかでない。
  • 64bit BAR構成にすると、データコピーが発生しない。約1.6GB/secと、ほぼフルの速度が出る

また、64bit対応したPCI Expressカードならば、ドライバが巨大なコモンバッファを確保してくれるようになります。コモンバッファというのは物理アドレスで連続したページされないメモリ領域です。DMA転送などの用途にも使えます。

32bitだと8MBくらいしか取れませんが、64bit版だと4GBまで取れます。これだけでも、64bitのPCI Expressにする意義があるといえるでしょう。

XILINXのXDMAコアを使って、PCI Express Gen2 x4でバスの帯域2.0GB/sのところ、上り下りとも1.6GB/sまでできました。

| | コメント (0)

2017.08.10

PCI ExpressのDMA転送を改善する

前回の記事ではWindowsが用意するしくみでは、1MBや2MBといったサイズでDMAが制限されていることを書きました。

具体的には、ドライバのコードで以下のようなものを書きます。

DEVICE_DESCRIPTION DeviceDescription;
RtlZeroMemory(&DeviceDescription,sizeof(DeviceDescription));
DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
DeviceDescription.Master = TRUE;
DeviceDescription.ScatterGather = TRUE;
DeviceDescription.Dma32BitAddresses = TRUE;
DeviceDescription.Dma64BitAddresses = FALSE;
DeviceDescription.InterfaceType = PCIBus;
DeviceDescription.MaximumLength = 0x10000000; // 256MByte
// DMAアダプタを作成
dx->dmaAdapter = IoGetDmaAdapter(dx->pdo, &DeviceDescription, &dx->NumOfMappedRegister);
KdPrint(("DmaAdapter: Num of Mapped registers =%d \n",dx->NumOfMappedRegister));

このコードは、DMAアダプタというものを獲得するコードなのですが、32bitのPCIバスを使って最大256MByteのDMA転送をするようなDMAアダプタを作ってくれ、と要求するものです。

ポイントは上の赤い字で記した、Dma64BitAddress=FALSEというところにあります。

64bitAddressesがFALSEだと、マップレジスタが256個しかとられません。

64bitAddressesをTRUEにしてみると、あら不思議、マップレジスタが65537個取れました。

Combuf_office_64

さくっと256MByte用のマップレジスタが取れたのでしょうか?

いや、PCI Expressも64bitでCPUも64bitなので、おそらくマップレジスタを使わずにDMA転送を行えるようになったのでしょう。

64bit版PCI Expressデバイスのすごいところはマップレジスタを使わないだけではなく、コモンバッファも巨大なサイズが取れるということです。

メインメモリ16GB積んだPCで、0xffffffffバイトのCommonBufferを要求したら、物理アドレス0x00000003-00000000から連続した4GBの長さのバッファが取れました。

Combuf_office_64_4gb

32bit版のPCIeとドライバでは4MBや8MBが限度だったので、4GBのバッファというのはすごいことです。

64bit版ドライバと64bit版デバイスはすごいですね。

本当にPCI Expressを64bitにするには、64bit BARを有効にしなければなりません。XILINXのXDMAコアでは、以下のオプションを設定します。

Xdma_64bit

これで64bit版のBARが有効になります。

そして論理合成してBitファイルを書き込んだら、一度再起動します。32bitBARから64bitBARに切り替えるには、デバイスマネージャからの無効→有効するだけではうまくいかないようです。

| | コメント (0)

2017.08.09

WindowsのDMAとMapRegister

スキャッタギャザーDMAを発行しようとして試行錯誤していたのですが、どうしても1MByte以上の転送を行おうとするとブルースクリーンになってしまいました。

最初はMapTransferという関数を使っていたのですが、オブジェクトの開放の手順がよくわからなかったので、途中からGetScatterGatherListを使うようにしたのですが、1MByteの転送をしようとすると物理アドレス(論理アドレス)のリストを作るだけで、実際の転送をしなくてもブルースクリーンになってしまいます。

100回くらい青い画面を出して、ようやくわかってきました。

スキャッタギャザーDMAでは、ユーザがmallocで確保したバッファが実際に割り当てられている物理メモリのアドレスを調べて、そこをめがけてFPGAからDMA転送するので、原理的にはデータのコピーが発生しません。

Sgtransfer

しかし、この方法には問題があります。

PCI Expressのアドレスはデフォルトでは32bitなので、4GBまでの転送先アドレスしか指定できません。パソコンのCPUのアドレスは4GBでは収まらないメモリ空間を持っています。それゆえ、メモリRD/WRを発行しても、メインメモリの先頭の4GBまでしかアクセスできないことになってしまいます。

そこで、Windowsでは、マップレジスタというものが用意されています。マップレジスタというのは、ハードウェアデバイス用の仮想メモリのようなもので、PCI Expressから指定された転送先アドレスを実際のDIMMの物理アドレスに変換する機能です。

つまり、PCI ExpressからメモリRD/WRで指定してくるアドレスは、パソコンのメモリの物理アドレスではなく、ハードウェア版のアドレス変換機構を通す前のアドレスなのです。これを論理アドレスといいます。

そして、物理アドレスと論理アドレスを変換する機能がマップレジスタなのです。

Mapregister_2

しかし、マップレジスタというのは実際に存在するわけではなく、そういう機能があったらいいな、というものをHALがエミュレートしているのです。

わけがわからないとは思いますが、つまりこういうことです。

  • MapTransferやGetScatterGatherListを実行すると、DMA転送先のアドレスとして、下位4GBを指すようなものが返される。
  • この下位4GBのバッファには、実際にユーザ用のバッファが割り当てられているわけではなく、DMA転送の前後で、カーネルがこっそりメモリコピーを行う

Mapregister2

Windowsはこんな仕組みでDMAを実行しているのです。

ブルースクリーンになってしまう原因はマップレジスタの数でした。私が新しく買ったWindows10 64bitマシンでは、デバイスドライバの中で「このデバイスは0x10000000(256MByte)のDMAを行う」と申告しても、マップレジスタを256個しか割り当ててくれませんでした。

Mapreg_office_32bit

マップレジスタ1個は1つの物理ページ(=4096バイト)のアドレス変換テーブルなので、1MByte分のアドレス変換しかしてくれないのです。これ以上の長さのDMAをしようとしてもマップレジスタが無いので、NULLを返してしまい、それを開放しようとしてブルースクリーンになっていたのですね。

家のPCでやってみたところ512個のマップレジスタが取れました。

Mapreg2

これなら2MBまでのDMA転送ができます。

実際に連続してスキャッタギャザーDMAをやってみたところ、アプリケーションレベルで測って毎秒1GB/secの速度で転送できました。

Dmardwr

しかし、1MBや2MBのサイズのDMA転送しかできないのですから、効率が悪いですね。

Windows7や8で32bit版ドライバを動かしていたときにはもっと確保できていたと思うのですが・・

重要なことは、スキャッタギャザーといってもユーザのバッファにDMA転送しているわけではなく、裏でカーネルがこっそりコピーしているということです。そのカーネルがこっそりコピーできるサイズが、1MBや2MBしかないのです。

| | コメント (0)

2017.08.08

特電の商品発送箱が変わります!

本日以降、特殊電子回路の商品発送に使用していた箱が変わります。

Beforeafter

いままで特電のSpartan-6やArtix-7の箱は上の写真の左側にあるような、白をベースとした箱に緑色のキラキラ印刷を施した箱で送っていました。箱の中には基板を納めるくぼみや、二階建ての引出があって、CD-ROMや付属品を入れるようになっていました。

しかし、この箱は組み立てるのが非常に大変で、引出の開け閉めもスムーズではなかったので、リニューアルしたいな・・とずっと思ってきました。

また、MITOUJTAGの梱包は、

Konpou8

のように白いダンボールにケーブルやCD-ROMなどを詰めて送っていましたが、これも、シンプルすぎて高級感がない。

実は、白い箱で送っているということで、何となく恥ずかしさを感じていました。

そこで、6つの面をフルカラーで印刷した新しい箱を作ることにしました。

Newbox1

どうですか?今までの特電ではないみたいでしょう。

側面にはバーコードが貼りつきます。

Newbox2

箱の中は硬質のスポンジで作った仕切りの中に、基板や付属品を納めることができるようになっています。

Newbox3

MITOUJTAGに関してもCD-ROMのケースと、Pocket JTAG Cableが気持ちよく納まるようにスポンジが加工されています。

Newbox4

これなら秋葉原の店頭に並んでいても恥ずかしくありませんね。

さて、このデザイン箱ですが、佐川急便の伝票や「取り扱い注意」シール、それから納品書封筒などを貼り付けてしまうとせっかくのデザインが隠れてしまいます。

そこで、発送用にもう1段外側に白い無地のダンボールでくるむことにしました。

Newbox5

そして、外側の箱に佐川急便の伝票やシールを貼りつけて、出荷です!

Newbox6

現在、

  • Cosmo-Z
  • Cosmo-K
  • MITOUJTAG BASIC/Pro
  • Spartan-6/Artix-7

が新しい箱での出荷となる対象です。

8月8日の出荷分より新しい箱でお届けします。

| | コメント (0)

Windows10におけるXDMAコア割り込みの発生方法

DMAの完了を知るためには割り込みの使用が必須です。

XDMAコアはかなり複雑なのですが、割り込みを利用するには開始コマンドを発行する際に、以下のようなレジスタ設定をします。

// 割り込みマスクの設定。転送失敗も含め、あらゆる要因を受け付ける
WRITE_REGISTER_ULONG(&DmaReg[0x0090 / 4], 0xfffffe); 

// DMA割り込みの許可
WRITE_REGISTER_ULONG(&DmaReg[0x2010 / 4], 0xffffffff);

DbgPrint("DMA descriptor set at %08x-%08x\n", dx->combufPhysAddr.HighPart, dx->combufPhysAddr.LowPart);

// DMAデスクリプタのアドレスを指定
WRITE_REGISTER_ULONG(&DmaReg[0x4080 / 4], dx->combufPhysAddr.LowPart); // デスクリプタのアドレスを書き込む
WRITE_REGISTER_ULONG(&DmaReg[0x4084 / 4], dx->combufPhysAddr.HighPart);
WRITE_REGISTER_ULONG(&DmaReg[0x4088 / 4], 0); // extra adjは0
WRITE_REGISTER_ULONG(&DmaReg[0x0004 / 4], 0xfffe7f); // DMA開始

これでDMAの完了時に割り込みが発生します。

さて、FPGAがPCI Expressに割り込みを発生させたら、ドライバできちんと扱わなければなりません。そうしないと、割り込みが発生しっぱなしになって、CPUが割り込み確認→戻る→確認→戻るを繰り返してしまいます。

なお、Windowsのデバイスドライバでは、割り込み発生時に呼び出されるルーチン(ISR)は極めて高いIRQLで呼び出されます。

IRQLが高いというのは、優先順位が高いということなのですが、マイコンのようなものをイメージしてはいけません。

優先順位が高いルーチンというのは非常にプログラミングがしにくいのです。まず、使用できるメモリが非常に限られてきます。ページドメモリ(スワップ対象のメモリ)が使えないとか、いろいろと制約が多く、カーネルAPIの多くも使用禁止です。

以下のTPInterruptHanderという関数は実際のISRの例ですが、割り込みサービスルーチンでは、割り込み要因の確認と、割り込みフラグのクリアを行い、DPC(遅延プロシージャコール)を行って戻します。

BOOLEAN
TPInterruptHandler(
    IN PKINTERRUPT  Interupt,
    IN PVOID        ServiceContext
)
{
    BOOLEAN interruptRecognized = FALSE;
    PTP_DEVICE_EXTENSION dx = (PTP_DEVICE_EXTENSION)ServiceContext;
    ULONG *DmaReg = (PULONG)dx->barVirtualAddress[1]; // BAR1
    ULONG DmaReason = READ_REGISTER_ULONG(&DmaReg[0x2044 / 4]);
    if (DmaReason & 1) {
        // bit0 : H2C channel interrupt
        WRITE_REGISTER_ULONG(&DmaReg[0x2018 / 4], 1); // mask IRQ, W1Cなので書き込むとマスク
        dx->InterruptReason |= 0x80000000; // 要因を保存
        interruptRecognized = TRUE;                      // このハンドラで処理した
    }
    if(interruptRecognized)
    {
        IoRequestDpc(dx->fdo, NULL, dx);                 // 遅延ルーチン呼び出し
        InterlockedIncrement(&dx->InterruptCount);       // 割り込み回数をカウント
    }
    return interruptRecognized;
}
割り込みサービスルーチンでは、基本的にあまり多くのことをするべきではありません。

XDMAではDMA(H2C)完了の割り込みが発生すると、BAR1のオフセット0x2044のbit0が'1'になります。そのため、ここではフラグを確認して、割り込みをマスクしてDPCの呼び出しをセットするだけです。

DPCルーチンは、IRQLが低いので比較的なんでもできます。DbgPrintも気兼ねなく使うことができます。

LONG tempReason;
tempReason = InterlockedExchange((LONG *)&dx->InterruptReason,0);

//バスマスタ完了割込み処理。
if (tempReason & 0x80000000)
{
    KeSetEvent(&dx->DmaEvent, IO_NO_INCREMENT, FALSE); // DMAイベントをセット
    tempReason &= ~0x80000000;
}

当ドライバでは上のようにして、カーネルのイベントをセットします。

DMA発生元のルーチンでは、

Timeout.QuadPart = -30000000; // 3秒待ち
status = KeWaitForSingleObject(&dx->DmaEvent, Executive, KernelMode, FALSE, &Timeout);
if (status == STATUS_TIMEOUT) {
    DbgPrint("NO DMA interrupt.\n");
    *BytesReturned = 0;
    return STATUS_TIMEOUT;
}

ULONG *DmaReg = (PULONG)dx->barVirtualAddress[1];
ULONG DmaStatus;
ULONG DescCount;

WRITE_REGISTER_ULONG(&DmaReg[0x0004 / 4], 0); // DMA停止
DmaStatus = READ_REGISTER_ULONG(&DmaReg[0x0044 / 4]);
DescCount = READ_REGISTER_ULONG(&DmaReg[0x0048 / 4]);
DbgPrint("DMA done:DmaStatus=%08x, Complete descriptor count=%d\n", DmaStatus, DescCount);
WRITE_REGISTER_ULONG(&DmaReg[0x2014 / 4], 0xf); // 割り込みマスクを許可する

*BytesReturned = length;
return STATUS_SUCCESS;

として、KeWaitForSingleObject割り込みを待ち受けます。上のコードでは3秒でタイムアウトするようになっています。

割り込みが発生したら、ISR→DPC→イベント発生→元のプログラムが再開という流れになります。

そして、BAR1の0x0004に0を書いてDMAを停止させて、その後、DMAのステータスと完了したDescriptorの数を調べています。

このように、割り込みを使ってDMAの完了を知ることができるようになります。

| | コメント (0)

2017.08.07

Windows10時代のデバイスドライバ開発とデバッグ

DMAのデバイスドライバを開発するため、Windows10での開発環境を整える必要が出てきましたので調べてみました。

いくつかの参考になりそうな記事がありますので、リンクを貼っておきます。

「Windows 10 でサンプル ドライバーをビルドするまで」
https://blogs.msdn.microsoft.com/jpwdkblog/2015/08/21/windows-10/

「ユニバーサル Hello World ドライバー (KMDF) の作成」
https://msdn.microsoft.com/ja-jp/library/windows/hardware/hh439665(v=vs.85).aspx

最初の「Windows 10 でサンプル ドライバーをビルドするまで」に従ってインストールします。

●Visual Studio 2015 Expressのインストール

まずは、VisualStudio2015のExpressをインストールしなければなりませんが、これが大変です。ExpressはCommunityに変わり、2015は2017に変わったので、2015 Expressをダウンロードしようとしても2017 Communityに飛ばされてしまいます。なかなかたどり着けません。

Visual Studio 2015 Expressのダウンロード先はこちらです

日本語版 https://www.visualstudio.com/ja/post-download-vs/?sku=xdesk&clcid=0x411&telem=ga

英語版 https://www.visualstudio.com/ja/post-download-vs/?sku=xdesk&clcid=0x409&telem=ga

上のページを訪れると自動的にダウンロードの保存ダイアログが出るので、保存します。

Getvsexpress

私は日本語版をインストールしました。

●Windows 10 SDKのインストール

Windows 10 SDKは難しくありません。下記のページからEXEをダウンロードする、を押せば手に入ります。

https://developer.microsoft.com/ja-jp/windows/downloads/windows-10-sdk

Getsdk

●Windows 10 WDKのインストール

下記のページにあります。

https://developer.microsoft.com/en-us/windows/hardware/windows-driver-kit

Getwdk

●ユニバーサル Hello World ドライバー (KMDF) の作成

参考リンクの「ユニバーサル Hello World ドライバー (KMDF) の作成」をしてみようと思っても、同じようにはいきません。まず、ソリューションエクスプローラで「追加」→「新しい項目」とやっても、Package Manifestしか出ないのです。

Addnewitem

C++やHのファイルのテンプレートというものがないためなのですが、テンプレートは以下のフォルダの中にあります。

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\VCProjectItems

しかし、VCフォルダに存在するのはVCProjectItems_WDExpressです。そこで、。VCProjectItems_WDExpressをコピーしてVCProjectItemsに名前を変えます。

Copywdexpress

プロジェクトに新しいC++やCファイルを追加できるようになります。

Addc

これで、ユニバーサル Hello World ドライバー (KMDF) の作成が作れるようになります。

●配置とデバッグ

ただ、その先にある配置やデバッガのところがうまくいきません。リモートデバッグの方法も試してはみましたが、参考リンクのようにはいきません。

そもそも2台のPCをつないでデバッグする・・というのは理想的ではありますが、やはり1台のPCでやりたいものです。

私の方針は以下のとおりです。

  • セキュアブートを無効にする
  • 開発用兼実験用PCで、カーネルモード署名の強制を無効にする
  • Windowsをbcdeditでテストモードにする

カーネルモードでのデバッグはDbgPrintを使います。KdPrintは括弧を二重にしないといけなかったり、何かと使いにくいのです。DbgPrintは

DbgPrint("DmaAdapter address = %x",addr);

のようにprintf感覚で使えてとても便利です。DbgPrintの出力は、DbgView.exeで見ることができます。

Dbgview

DbgView.exeは以下のリンクから入手できます。

https://technet.microsoft.com/ja-jp/sysinternals/debugview.aspx

DbgView.exeを管理者モードで起動して、Captureのオプションを下記のように設定すれば、DbgPrintの出力を見ることができます。

Dbgprint2

●ドライバの日付について

基本的にビルドしてテストしての繰り返しなので、面倒なことはしたくありません。Visual Studioでビルドしたドライバには、自動的にinf2catやsigntoolで署名が施されます。

ただし、日付がUTCなので日本の午前0時を過ぎると翌日になってしまい、未来の日付は使えないとエラーになってしまいます。そこで、下記のオプションを設定する必要があります。

Inf2cat

●ドライバの署名について

Visual Studioでプロジェクトを作ると、オレオレ証明書ができているようです。

Debugフォルダの中に.cerというファイルがありますので、これを信頼されたルート証明機関にインストールします。

Sign2

これで、自分のPCだけで使えるAuthenticode署名ができるようなのですが、

Sign3

ドライバのインストールで失敗するようなので、私はWindowsをテストモードにして、署名の強制を無効にして使っています。

ざっと駆け足で説明しましたが、このような手順でWindowsのデバイスドライバを開発できるようになると思います。

| | コメント (0)

2017.08.06

XILINX XDMAの使い方と速度

XILINXのXDMAコアの使い方を調べています。

XDMAはディスクリプタベースのスキャッタギャザーDMAをサポートしているということです。

これだけだと何のことかさっぱりわからないと思いますが、ディスクリプタというのはDMAの転送元アドレスや転送先アドレスを書いたリストのことで、スキャッタギャザーというのは細かいDMAを大量に発行することを意味します。

さらに詳しく説明しますと、ユーザ空間でmallocやnewで確保したメモリというのは、一般的には物理メモリ上では細かく断片化しています。

イメージ的には下の図のような感じになります。

Sg

断片化の大きさや数、長さは常に変わっているので上の図のアドレスやサイズはあくまでもイメージです。数十キロバイトサイズの大きな連続したブロックに割り当てられていることもありますし、64バイトしかないこともあります。

とにかく、ユーザのバッファは物理(論理)アドレス上では断片化しているので、何番地~何番地までのメモリの内容を一度にFPGAに転送することはできません。

そこで、この断片化されたリストを送って、細かいDMAをたくさん発行するのがスキャッタギャザーです。スキャッタギャザーとは、散乱したものを集めるという意味です。

この断片化したパソコン内の物理メモリのアドレスとFPGAの転送元/先アドレスの情報を記したものがディスクリプタです。XILINX XDMAのディスクリプタは8ワード長で、形式は以下のとおりです。

Descr

オフセット0の上位16bitはMagicワードで、ここには0xad4bを指定します。下位8bitに0x13を書いておくと、転送終了後にSTOP、COMPLETE、EOPというイベントを発行します。

Lenにはバイト単位で長さを指定します。

src_addrはDMA転送元のアドレスです。DMA WR(Host to Card)の場合はPC上のメモリの物理アドレス(論理アドレス)を書いておきます。

dst_addrはFPGAのAXIに発行されるメモリのアドレスです。

nxt_addrは次のディスクリプタが格納されたPC上のメモリの物理アドレス(論理アドレス)です。スキャッタギャザーなので、複数のディスクリプタをリストにして使えるのですが、今回は1個のDMAを発行するのでnextポインタには0を指定しておきます。

このディスクリプタをパソコン内のメモリに格納しておいて、DMAが開始すると、FPGAは最初のディスクリプタをDMAで読み出して、そのディスクリプタの内容に従ってDMAを発行します。

さて、ディスクリプタはパソコンのメモリの中に書いておく必要がありますが、どこに書けばよいのでしょうか?

基本的に、mallocなどで確保したメモリはページアウトされている可能性があるのと、不連続なので、ディスクリプタには不向きです。

そこで、断片化していない連続した非ページメモリが最適です。そういうメモリは、AllocateCommonBufferという関数で確保します。AllocateCommonBufferは単純な関数ではなく、DMAアダプタを作ったあとでその中に関数ポインタとして存在しています。つまり、DMAのバスのタイプによって実装が変わる関数なので、単純ではありません。

コモンバッファ(共有バッファ)というのは、仮想アドレスと、物理アドレス(論理アドレス)の両方を知ることができるバッファです。2種類のアドレスでアクセスできるのでコモンバッファといわれているようです。

そういうわけで、AllocateCommonBufferで確保したコモンバッファにディスクリプタを作ります。

ULONG *desc = (ULONG *)dx->combuf; // 作ったコモンバッファの仮想アドレス
desc[0] = 0xad4b0013;
desc[1] =  100; // bytes
desc[2] = dx->combufPhysAddr.LowPart; // src addr low
desc[3] = dx->combufPhysAddr.HighPart; // src addr high
desc[4] = 0; // dest addr low
desc[5] = 0; // dest addr high
desc[6] = 0; // next addr low
desc[7] = 0; // next addr high

// BAR1にDMAコントロールレジスタがある
ULONG *DmaReg = (PULONG)dx->barVirtualAddress[1];

// DMAデスクリプタのアドレスを指定
WRITE_REGISTER_ULONG(&DmaReg[0x4080/4], dx->combufPhysAddr.LowPart); // デスクリプタのアドレスを書き込む
WRITE_REGISTER_ULONG(&DmaReg[0x4084/4], dx->combufPhysAddr.HighPart);
WRITE_REGISTER_ULONG(&DmaReg[0x4088/4], 0); // extra
WRITE_REGISTER_ULONG(&DmaReg[0x0004/4], 0xfffe7f); // DMA開始

そして、BAR1の0x4080,0x4084にディスクリプタのあるPC上の物理アドレスを指定し、BAR1の0x0004にDMA開始のコマンドを書き込みます。本当は0x000001でいいのですが、エラーやその他の停止条件もトリガするため0xfffe7fを書いています。

このようにするとXDMAのコアが動き出します。実際に100バイトの書き込みを行ってみた時の波形は以下のようになりました。

Dmawr100_2

AXIの転送サイクルとしては2回発行されていて、最初に4クロック(16バイト×4)で64バイトが転送され、次に32バイトと4バイトが転送されています。

データバスは128bitなので、wstrbが0xffff→0x000fと変化することで4バイトの書き込みに対応します。

次の波形は16kByteの転送を行ったときのものです。

Xdma_speed

小さな転送がたくさん行われていて、全体が終わるまでに約9.5μ秒かかっています。ここだけみれば1700MB/secの速度で転送できていることになります。

なお、1つ1つの転送は256nsの時間で行われているので、32クロック=512バイトです。

Dmawr_cont1

偶然によっては、転送先アドレスが0で始まらない場合もあって、wstrbがFFFFとならず1クロック余計にかかることもあります。

Dmawr_cont2

これでDMAの発行ができるようになりました。

次はスキャッタギャザーに本格対応させるために、デバイスドライバの開発環境を整えることにします。

| | コメント (0)

2017.08.05

Kintex-7のPCI ExpressコアのWrite速度

Kintex-7にAXIベースのPCI Expressのコアを入れて速度を測ってみました。

使ったのは、Cosmo-K+というボード。

1478579823_cosmok

PCI ExpressはGen2のx8なので、毎秒2GByteが理論上の最高速度なのですが、書き込み速度でさえ、65MB/s程度と、わずか3%の速度しか出ていません。

Pcie_rdwr

この回路で使っているのはXILINX XDMAコアですが、今回はDMAポートではなくAXI BYPASSポートを使っています。

Axi_bypass_2

AXI BYPASSのポートにBRAMをつないでいます。BRAMはすぐに応答を返すのでそこがボトルネックになっているというわけではありません。

そこで、XMDAコアからBlockRAMの間のAXIの配線を全部引き出して、MITOUJTAGで波形がみられるようにRTLのコアを横にいれました。

これでAXIの信号を見ることにします。

Pcie_dma

すると、こんな波形が得られました。

Pcie_wr

開始部分を拡大してみます。

Pcie_wr2

128bit幅で125MHzの転送なので、1回のバスサイクルで16バイトを並列に転送できます。ですが、この図を見てわかることは、WSTRBが000F 00F0 0F00 F000と、32bitずつ4回にわけて転送しています。

また、AWLENが00(=256)を指しているのに毎回の転送でLASTが送られてきてしまって、バースト転送が行われていません。

このため、32bitの転送で平均60nsくらいかかってしまいます。4MBytes/0.06us=66MBytes/secなので、計測結果とも一致します。

なぜこんなに遅いのかはわかりませんが、XILINXのAXIベースのPCI Expressコアは、PCI ExpressのWrite転送を小分けにしてしまうようです。

やっぱりDMAを使わないとだめでうね。

| | コメント (0)

2017.08.02

Windows10におけるデバイスドライバ

ASUS製のWindows10のマシンで、OSを再インストールしたら、Kintex-7のPCI Expressボード「Cosmo-K」用のデバイスドライバが動かなくなってしまいました

あれ・・・?買ったときには動いていたのに。なぜ??

Drv3_2
Drv4

ちゃんとSHA256でカーネルモードの署名をしているのに、署名が検証できないと出てしまいます。

署名や証明書に問題はないはずなのですが・・

Drv5Drv4_2

どうやらWindows10では、署名だけではドライバは動かないようなのです。

詳しいことは下記のページにありました。

https://blogs.msdn.microsoft.com/jpwdkblog/2016/10/26/windows-10-anniversary-update-signing-policy/

Windows10のAnniversary Update以降では、自分で署名したドライバは動かず、Microsoftが署名したドライバでないと動かなくなったようです。

この仕様を自分で回避する方法は4つあって、

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

のどれか1つが満たされていれば、自分で署名したドライバでも動くようです。

つまり、Microsoftの考えでは、昔からアップデートして使っていたユーザや昔から存在したドライバは使えるように温情をかけてやるけど、新しく作ったドライバはMicrosoftの管理下に置かせろ、というわけです。

我々開発者は、ドライバの開発の段階ではデバッグやビルドを繰り返すわけですから、いちいちMicrosoftの署名など申請するわけにはいきません。

自己防衛できることはセキュアブートの無効化くらいしかありません。

セキュアブートについて調べてみると、セキュアブートというのは署名のないOSは起動させないようにUEFI(BIOS)が制限するというもののようです。ウィルスとかマルウェアがOSの重要なファイルを書き換えて乗っ取るのを防ぐ仕組みのようで、UEFIレベルで証明書とか署名とかややこしいことをするようになったようです。

はぁ、なんとも生きづらい世の中になったものです。

私が自宅で使っているASUSのPC()は、UEFIにセキュアブートを無効にする、という項目はなく、セキュアブートの欄は灰色で常にEnabledになって変更できませんでした。

ですが、OSのタイプをWindowsではなく、Other OSにしたところ、セキュアブートが無効にできました。

セキュアブートが有効になっているかどうかは、Windowsの「ファイル名を指定して実行」のところで、msinfo32.exeと打つと出てくる以下のツールで見ることができます。

Drv8

この状態ならば、無事にドライバの読み込みができました。

Drv1Drv2

これで一件落着なのですが、あくまでも一時的な回避策です。

商品として売る以上、お客様に「セキュアブートを無効にしてください」とお願いするのもよくないので、最新のカーネルモードドライバの作り方を勉強して、Microsoftの署名をもらう方法を調べたほうがいいかもしれないと思います。

| | コメント (0)

2017.08.01

振込手数料はどちらが負担するべきか

ある会社さんに納めた成果物の代金が、324円少なく振り込まれていることに気が付きました。

問い合わせてみると、振込手数料を差し引いた金額とのことでした。

「振込手数料はご負担ください」と伝えておいたのに差し引かれたため激おこぷんぷん丸になっていたのですが、そもそも振込手数料を差し引いて支払う(つまり受取人側に負担させる)という感覚が信じられないので、ツイッターのアンケートをしてみました。

いったい、みんなはどう思っているのか。

アンケートの結果がこれです↓

Tesuuryou

なんと、23%くらいの人が受取人が負担するべき、と考えているようです。しかも10%の人は「ご負担ください」と書いてあっても差し引いてしまうようです。

この問題に関しては、いろいろなコメントが寄せられました。

    • 逆に請求金額そのまま振り込んでくださる会社に驚くくらい(^^;
    • 「集金原則」という商習慣ですね。僕は振込み手数料ご負担下さいと請求書に書いてますがそれでも2-3割の会社は手数料引いてきます。
    • 日本の商習慣では、受け取る方が手数料を支払うのが一般的ですね。商社さんとか普通にそうですし。
    • てか、セコい。

法律的にはどちらが負担するべきと決まっているわけではありません。年代や地域、業種によって差はあるのでしょうが、この受取人が負担するという商習慣の起源がなんとなくわかってきました。みなさんのコメントを見てみると、

    • 銀行振り込みの前は、直接集金に行っていたわけですが、請求する側が交通費等をいただく事はしません。それと同じ理屈になります。
    • 説教されたことがあります。集金に来ないのだから、その手間ひまを考えたら、手数料引かれて当然と、、、
    • まだ何も知らない時代に「振り込む時は手数料引いて振り込むもんだ」ってドヤ顔で教えてくれた奴、普段からセコい奴だったので、そのイメージもあるんだが。

つまり、

  1. 昔々、オンラインでの銀行振込が一般的ではなかった時代は、商品を売った側は顧客を一軒一軒回って集金していた。(もちろん手形・小切手もあったろう)
  2. 集金に来たら全額払う意思はある。
  3. 支払う側は、銀行振込の面倒な手続きをするのだから手数料くらい受取側が負担しろ、さもなくば集金に来い、という考え方をするようになった。
  4. そういう考え方の先輩に教えられて、受け取り側が負担するべき、という世代が一定割合育った。

ということではないかと思います。

たしかに昔の振込は、銀行の窓口で紙を書いて、何十分も待たされる面倒なものでした。現金書留、郵便振替、定額小為替とか、いずれも面倒で手間がかかっていたので集金に来てくれたら楽というのはわかります。

ですが、今は、どこの銀行もオンラインでネットで振込できます

文書扱い振込とか集金とか、といった時代ではありません。

もう、受取人負担という考えはやめましょうよ。


みんな満額受け取ることを期待して請求書を書いています。勝手に324円とか864円とか引かれたら、そういうことをする会社への信用はものすごいマイナスになりますし、経営状態がやばいんじゃないか、とか体質が古いんじゃないかと思われてしまいます。

さて、たしかに法律的にはどちらが負担するかは決まっていません。が、手数料を差し引くことは代金の減額を意味することですから、下請法という法律が出てきます。

下請法によれば「あらかじめ合意があれば」手数料を差し引くことは認められるのですが、合意はあくまでも抜け道です。一律に禁止してしまうと商習慣を変えられない人たちのために配慮したのでしょう。合意が必要ということは、原則として満額支払うべきというのが法の趣旨です。

下請法が適用されない小さい会社同士の取引なら違法ではない・・ではなくて、差し引くこと自体が問題なのです。

差し引くことが地域や業種の商習慣というなら、その商習慣が法の抜け道を利用している異常なものなのです。外の世界では通用しません。

それに、たった108円や324円で信用を地に落とします。差し引いた本人は感じていないかもしれませんが、もう二度と取引をしたくないと思わせるほど、相手を不快にさせる行為です。

明日から、日本全体で即刻、受取人負担はやめましょう。

ニコニコ満額払いでみんなハッピー

| | コメント (65)

« 2017年7月 | トップページ | 2017年9月 »