e-tipsmemo

ごった煮

Rust パーセントエンコーディング

パーセントエンコーディング

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~
以外の文字を{%[hex]}*nの組み合わせに置き換える。
HTTPリクエストなどで送るときに必要。

fn urlencode(my_str: String) -> String {
    let unreservedchars =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~".to_string();
    let mut encoded = String::new();
    for c in my_str.chars() {
        match unreservedchars.find(c) {
            Some(_) => {
                encoded.push(c);
            }
            None => {
                let mut bytes = [0; 3];
                c.encode_utf8(&mut bytes);
                let percented = match c.len_utf8() {
                    1 => format!("%{:X}", bytes[0]),
                    2 => format!("%{:X}%{:X}", bytes[0], bytes[1]),
                    3 => format!("%{:X}%{:X}%{:X}", bytes[0], bytes[1], bytes[2]),
                    _ => "".to_string(),
                };
                encoded = format!("{}{}", encoded, percented);
            }
        }
    }
    encoded
}

こんな感じか(?)
あんまり速くないと思う。

しかし、reqwestのUrl structureを使えばqueryを組み立てるところまでやってくれることに書いてから気付いた。

    let mut url = Url::parse("https://www.google.co.jp").unwrap(); //ここはなんかのURLが必要。
    url.query_pairs_mut()
        .append_pair("hoge", "aaa")
        .append_pair("piyo", "あ")
        .append_pair("foo", "漢字")
        .append_pair("bar", "ß");
    println!("{:?}", url.query().unwrap());

結果

hoge=aaa&piyo=%E3%81%82&foo=%E6%BC%A2%E5%AD%97&bar=%C3%9F

文字コードはUTF8を利用しているのでUTF8で出る。

依存を見ると
f:id:katakanan:20180401041940p:plain
https://crates.io/crates/percent-encoding

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

マスタリングTCP/IP 入門編 第5版

マスタリングTCP/IP 入門編 第5版

Oscilloscope選定

以前は秋月で買た「秋月3万オシロ」を利用していた
www.owonjapan.com
が、スペック的にもの足りない気がしてきたので新しく購入するオシロスコープを選定した。
と言っても、Agilentの普通のInfiniiVisionシリーズは高い

スペックがいいのが欲しいが、こだわり過ぎずに1GSps以上の性能を持つもので
(帯域は値段と相談する)
最近勢いのある中国製格安オシロスコープを加えて検討した。
書いてあるオシロスコープは同価格帯のものの商品例を載せた。
探せばもう少し良いものがあるかもしれない。

Keysigt InfiniiVision1000X

キーサイト (KEYSIGHT)InfiniiVision 1000X オシロスコープ 50MHz 2ch 1GS/s, EDUX1002A

キーサイト (KEYSIGHT)InfiniiVision 1000X オシロスコープ 50MHz 2ch 1GS/s, EDUX1002A

InfiniiVisionシリーズでありながら6万という安めのシリーズ。

50MHz 2ch
サンプリングレート:1GSa/s
メモリ長:100kpts標準
ディスプレイ:7インチWVGA
チャンネル数:2ch

キーサイトのオシロスコープは他社のにくらべてメモリが長い気がする。(個人的な感想)
またUIが綺麗でわかりやすいし、サクサク動いて良い。

しかし調べればすぐにわかるがこれはRigolのOEMなのではないかという話。
Keysigtブランドで売っているので安心できると思われる。

岩崎通信機 DS-5105B

●最高サンプリング速度:1GS/s、等価サンプリング:5GS/s
●最大メモリ長:1024kポイント
●デジタル・フィルタ機能
●異常現象の発見に便利なピークディテクト機能
●20種の自動測定機能
●Pass/Fail機能
●6桁の周波数カウンタ機能内蔵
USBメモリに画像を保存

Amazonの購入評価が無いのが気になる。
岩通のオシロスコープだが原産国は中国と書いてある。

【サイズ、分解能】5.7型(320 x 234ピクセル)

画面が小さく、解像度が低いのが残念・・

RIGOL DS1054Z

【アナログ周波数帯域】50MHz
【最高サンプリング速度】1GSa/s(1チャンネル)、500MSa/s(2チャンネル)、250MSa/s(3/4チャンネル)
【最大メモリー長】12Mポイント(1チャンネル)、6Mポイント(2チャンネル)、3Mポイント(3/4チャンネル);オプションで増設可
【ディスプレイ】7.0型WVGA(800*480)TFT液晶、64輝度諧調レベル

前者2つのと近い値段で4チャネルと多い。
しかし、4チャネル動作では250Mspsになってしまうようだ。
さらに帯域が物足りない気がする。
しかしRIGOLのとあるオシロスコープは内部のファームウェアを書き換えることで帯域を200MHzにしてしまうことができるらしい。
www.instructables.com
(※やったことはないので自己責任で)

OWON SDS7102

スペック表があるが引用するのは省く。
前者2つのオシロスコープに比べてAmazon評価が少し劣る?
日本語マニュアルがついているらしい。
たしか秋月にも売っていた気がする。

写真は綺麗で評価もそれなりに良さそうだが
以前所持していたPDS5022Tがちょっと微妙だったので
OWONはパス(他社のものが買ってみたいというのもある)

Hantek DSO4xxx(B|C)

4CH 100MHz帯域幅デスクタイプオシロスコープ
高度なデジタルトリガシステム、高いトリガ感度、低いトリガジッタ
高解像度7インチ64KカラーTFT
1GS / sサンプルレート
最小測定範囲:500μV/ div

Qingdao Hantek Electronic Co., Ltd.
Hantekのオシロスコープの製品ページに行くとわかるが多くのラインナップがある。
据え置き型から、USB接続タイプのものもある。
帯域は80MHz, 100MHz, 200MHz, 250MHzとある。

続きを読む

Rust Build Windows DLL on WSL 2

e-tipsmemo.hatenablog.com
このような記事を書いたが、

.cargo/configの記述がこのままだと
i686-pc-windows-gnuコンパイルすると、

C:\projects\rust\src/libpanic_unwind/gcc.rs:292: undefined reference to `_Unwind_Resume'
          collect2: error: ld returned 1 exit status


error: aborting due to previous error

error: Could not compile `hello`.

というエラーがでるのを忘れていた。

このエラーに対する解決策は、
Rustでクロスコンパイルしてみた | 思案試行
のブログより、

.cargo/config
の記述に追加する。

[target.i686-pc-windows-gnu]
linker = "/usr/bin/i686-w64-mingw32-gcc"
rustflags = "-C panic=abort"

Rust Build Windows DLL on WSL

以前にこのような記事を書いたが、
e-tipsmemo.hatenablog.com

Rustupにformatterが標準機能になったらしいので
cargoからインストールするのではなく、

rustup component add rustfmt-preview

を行って、.vimrcに

let g:rustfmt_autosave = 1

だけを書けばよくなった。(と思われる)

Cross Compileの設定

$ rustup target list | grep windows
i586-pc-windows-msvc
i686-pc-windows-gnu
i686-pc-windows-msvc
x86_64-pc-windows-gnu
x86_64-pc-windows-msvc

x86のDLLが作りたいのでi686の方を入れる。

$ rustup target add x86_64-pc-windows-gnu
$ rustup target add i686-pc-windows-gnu

このままビルドするとエラーでるので

$ sudo apt install mingw-w64

プロジェクト作成

$ cargo new hello

これでsrcにlib.rsだけのcrateができる。

Cargo.tomlと同じ回想に.cargo/configを作って

$ cat .cargo/config
[target.i686-pc-windows-gnu]
linker = "/usr/bin/i686-w64-mingw32-gcc"

[target.x86_64-pc-windows-gnu]
linker = "/usr/bin/x86_64-w64-mingw32-gcc"

とする。

このプロジェクト自体を常にi686向けにビルドしたい場合、

[build]
target="i686-pc-windows-gnu"

を追加する。

DLL出力設定

Cargo.tomlに以下を追記する。

[dependencies]
winapi = "0.2.7"
user32-sys = "*"
libc = "*"

[lib]
path = "src/lib.rs"
crate-type = ["cdylib"]

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winuser"] }

後々 kernel32 crateも必要になるかもしれない。

とりあえず

cargo build

でビルドできることを確認する。

DLL作成

lib.rs

呼び出し規約を合わせるための
"C"や"system"といった修飾子がよくわからない。
とりあえず"C"にしたところdependency_walkerでもdllexpでも、i686、x64のDLLともに、関数がexportされているのが確認できた。
DLLに対する様々なイベント時によばれるDllMain関数は”system”にした。
www.unknowncheats.me


lib.rsによって生成されたDLLをdependency_walkerで見たところ。
f:id:katakanan:20180320211425p:plain
helloが見えていればOK

動作を確かめるためにVisual Studio 2017で以下のプログラムを実行した。
生成されるexeと同じ場所にrustで作ったDLLを置くか、外部参照として追加する必要がある。

DLLのATTACHされたイベントが飛んできて、何回かDLLに関するイベントが飛んできた後に、helloが呼ばれたときのMessageBoxが出現する。
f:id:katakanan:20180320212426p:plainf:id:katakanan:20180320212351p:plain

EZ-USB FX2 Device Descriptor

e-tipsmemo.hatenablog.com

SlaveFIFOの利用を始める。
ベースはBulkloopサンプルであり、TD_Init、TD_Poll、デバイスディスクリプタを編集することになる。
http://www.cypress.com/file/386321/download
のp11から。

ここが項目ごとにまとまっている。
EZ−USB FX2LPの概要 (その2)

ここのp32からレジスタの概要が載っている
http://www.cypress.com/file/113936/download

詳細は
http://www.cypress.com/file/126446/download
のp211からである。

エンドポイントは以下の12パターン
f:id:katakanan:20180103104645p:plain
の中から選ぶが、上記PDFのサンプルコードによると、
EP2をOUTの512byte 4重バッファ。
EP6をINの512byte 4重バッファに設定しているので
Device Descriptorもその設定に合わせる。
画像中の設定5に対応する。

Interface Descriptorなどはほとんど変更しなくても良さそうなので
Endpoint Descriptorなどを変更していく。

;; Endpoint Descriptor
      .db   DSCR_ENDPNT_LEN      ;; Descriptor length
      .db   DSCR_ENDPNT         ;; Descriptor type
      .db   0x04               ;; Endpoint number, and direction
      .db   ET_BULK            ;; Endpoint type
      .db   0x00               ;; Maximun packet size (LSB)
      .db   0x02               ;; Max packect size (MSB)
      .db   0x00               ;; Polling interval

Endpoint Descriptorの上から3つ目のエンドポイント方向と番号は以下のようになっている。
f:id:katakanan:20180316120721p:plain:w300
DIRは1が入力、0が出力。

EP2ならOUTなので0x02
EP6ならINなので0x86となる

EP4,8は使わないから書かなくてもよいかと思われたが、それではプログラムを書き込んだ際に認識しなかった。
最大パケットサイズは0x0200(512byte)の上位8bitを示している。

USBを差し込んだときにPC側がもらうデバイスディスクリプタをWDKのツールによって確認することができる。
WDKはWindowsデバイスドライバを開発するときに必要になるが、
Visual Studio 2015をインストールすれば自動でインストールされた気がする。
デフォルトでは
C:\Program Files (x86)\Windows Kits\10\Tools\x64\usbview.exe
にそのツールがある。

USB2.0インターフェース設計術

USB2.0インターフェース設計術

rust obj loader

3Dモデルを読み込むのにOBJファイルローダーを作ろうかと思った。
が、優秀なローダーがあるのでそれを利用したほうが良いので
tobj crateの紹介
GitHub - Twinklebear/tobj: Tiny OBJ Loader in Rust

Cargo.tomlに追記。

OBJファイルを用意する必要がある。
立方体などであれば手で書いてもいい。
OBJファイルフォーマット

とりあえずMayaで板を作る。
f:id:katakanan:20180311231042p:plain

テストコードを実行
一緒にエクスポートされるmtlもないとエラーになる。
f:id:katakanan:20180311231217p:plain

idxとvなどを利用して自作の構造体に変換していけばよさそう。

Rust レイトレーシング ⑩ 三角形

ポリゴンの衝突判定のためにレイと三角形の衝突を実装した。


球と同様にHITトレイトを実装する。
三角形との交差判定は
risalc.info
にある通り。
f:id:katakanan:20180217175646p:plain:w500

面内のベクトル\overrightarrow{h}は、三角形の法線\overrightarrow{n}と直行するのでそこからtがわかる。

ベクトル\overrightarrow{h}を求め、三角形を張る\overrightarrow{a}\overrightarrow{b}を基底とした、\overrightarrow{h}の座標(u, v)を求める。

uvがこのような条件のとき、交点は三角形内にある。

Traitをこのように変更することで、これを実装した構造体をスレッド間をアトミックなリファレンスカウンタを持つポインタを用いて、
共有できるデータとすることができる...(?)

なので、少し変更。


f:id:katakanan:20180217181311p:plain:w300

Programming Rust: Fast, Safe Systems Development

Programming Rust: Fast, Safe Systems Development

プログラミングのための線形代数

プログラミングのための線形代数