2017/10/21

[c/c++]URIスキームはラベル扱いになってしまう

お仕事でプログラムを作っている。
まだテスト段階なので仮実装が多く、忘れないように#warningなどで目印にしている。


だから、ビルドするとwarningはたくさん出てしまうのだが、エラーは出ないようにしている。
しかし、ソースを見直しているとこんな行が出てきた。

xxx {
   ...
   for (...) {
      ...
  }http://www.yahoo.co.jp/
}

参照したURLをコメントに書こうとしたのだろうが、間違えてソース中にそのまま貼り付けてしまったようなのだ。

にもかかわらず、エラーになっていない。
なんでだ?


単純なソースファイルにしてみる。

int main(void)
{
    http://www.yahoo.co.jp/
    printf("Hello, World!\n");
    return 0;
}

エラーにならないし、ちゃんと動く。


-Wallをつけてようやく分かったのだが、これは「http」というラベル扱いになったのだ。
こう書くと、printfは実行されずに終了する。

int main(void)
{
    goto http;
    printf("Hello, World!\n");

http://www.yahoo.co.jp/
    return 0;
}


何か使い道はないかと考えたが・・・ないな。
「なんか間違ってるよ」と思われるのがオチなので、やめておこう。

2017/10/19

[git]forkして作業するか、forkせずに作業するか (1)

githubでソース管理することを考えている。
まだ一人なので何とでもなっているのだが、そのせいでチーム開発向けのルールが考えついていないのを、なんとかしようとしているのだ。


いつもは、なるべく作業前にブランチを作って、そこで作業して、終わったらpull requestしてマージしてもらう、というやり方にしている(一人しかいないので、自作自演なんだけどね)。


まず、各作業をする人が同じリポジトリを使った方が良いのか、リポジトリを各人で作ってforkした方が良いのか、というので悩んでいる。

最初は同じリポジトリで試して、今は別アカウントでforkしている。
前者が使えるのは、リポジトリへのアクセス権をもらった場合(organizationに追加してもらうなど)だけのようだから、混ぜてやるなら後者しかないか。

前者の利点は、forkしていないから、git pullなどとすれば最新版がmergeできるというところか。
後者だと、相手のリポジトリにmergeしてもらったあと、fork先からのmergeという手段になってしまうと思うのだ。
GitHubでFork/cloneしたリポジトリを本家リポジトリに追従する - Qiita

今はそれでやっているのだが、けっこうfork先からのmergeを忘れてしまう。。
私が悪いと言えばそれまでなのだが、なまじどちらにも同じ権限を持っているだけに、どっちのリポジトリにマージしたのか忘れてしまうこともあった。

そのちょっと前までは、forkしたリポジトリでブランチを作って、fork先にpull requestしてmergeして、fork先からfork元にpull requestする、という2段階でやっていたのだが、さすがに面倒だったのでやめた。
githubでも、pull requestすると、最初にfork元が候補に出てくるから、直接やる方を推奨しているんじゃないかと思っている。


書いていて気付いたが、組織内であればforkさせる理由はあまりないか。
間違ってmainlineを直接編集してしまうという心配はあるのだが、それを避けたければREAD権限にして...forkしてpull request出すのが安全なのか?
branchにprotectをかけるということができるようだから、mainlineだけ保護してしまえばよいのかな?


しばらく、protectして使ってみて、また考えよう。

2017/10/18

[win]SysinternalsのStrings.exeと他のstringsで結果が違うがわからん

WindowsでSlackアプリを使っている。
未読があると、タスクトレイアイコンに赤か青のドットが表示されるのだが、見逃さないように通知領域に出している。

image

Slackアプリは更新が多く、困ったことに更新されると通知領域に表示させる設定がOFFに戻ってしまうのだ。
デスクトップ版もUWP版も変わらないので、OS側なのかな?


私の心が狭いのか、このOFFに戻ったときがどうにも腹立たしい。
「設定アプリ>個人用設定>タスクバー>タスクバーに表示するアイコンを選択してください」と、たどるのが深いのが、また腹立たしさをいや増す。

タスクバーの設定画面までは通知領域のコンテキストメニュー表示から飛べるのだが、最後の画面にたどりつくには、そこからリンクをクリックせんといかん。
設定画面への直接のURIはいくつかあるのだが、この画面に対しては存在しないようだった。


というのが、前置き。

調べていると、この記事が見つかった。

山市良のうぃんどうず日記(102):Windows 10 Fall Creators Updateで増える「設定」は「ms-settings:URI」で狙い撃ち (2/2) - @IT

この人は、DLLからURIを探し出して、Microsoftのページに書いていない画面も探すことに成功している。
私も同じことをしてみようと、フォルダまで飛んで、cygwinを立ち上げてstringsで文字列を出し、grepでフィルタ挿せた。
が、"ms-settings"が1つも出てこない・・・。

記事の時期のせいかもしれんと思ったが、2017年7月なので、それはなさそうだ。
念のため、Bash on Windows on Ubuntuでもやってみたが、結果は同じ。
むう。

最後に、書いてあるとおりにSysinternalsのStrings.exeでもやってみることにした。
こっちは、出てくる。
結果が全然違うのだ。
なんでー!


あり得るとしたら、Windowsだから2byteのUnicodeを使っていて、Sysinternalsはそれに対応しているから・・・か?
理由はよくわからんものの、Windowsアプリの文字列を取ってくるときにはSysinternalsの方を使うのが無難だということはわかった。

2017/10/17

トラックボールを使ってみる

技術ネタではないのだが、今回はトラックボールに持ち替えて1日目になるので、感想を書いておく。


歳を取ってきて、マウスによる腱鞘炎に悩むことも多くなった。。。
私の場合は、右人差し指の第2関節か、右親指の第2関節がよくやられる。

親指の方はよく理由が分からないのだが、人差し指はホイールを動かす量が多い場合だということがわかっている。
デバッグしていて、ひたすらログを上下に眺める状況が数日続くと、もう危ない。

ロジクールの、ホイールがするする回転するマウスを使うようになって軽減したのだが、限界はある。
中指で代用することもあるのだが、使い勝手が悪い。


マウス以外の選択肢となると、トラックボールかペンタブか。
ペンタブは用途に合わないので、トラックボールか・・・と思ったが、踏ん切りが付かない。

そういうとき、飲み会でトラックボールに変えた人がいたので、思い切ってやってみたというわけだ。


買ったのは、ケンジントンのトラックボール。
ネットで買うともっと安いのだが、ヨドバシでは5,100円だった。

image

前方後円墳みたいな見栄えになっているが、下の方は付属品のパームレストだ。
付けた方がよいのかどうかは、まだ悩んでいるところである。

ボタンは2つしかないが、アプリによって同時押しもカスタマイズできる。
私は中央ボタンに割り当てた。
ブラウザでは「戻る」が使えると便利なのだが・・・と思ったら、アプリ単位での割り当てもできた。

ホイールは、ボタンの周りをくるくる回すことになる。
私は親指と薬指で回している。
これのおかげで、スクロールはかなり楽になった。

ホイールのチルトによる水平スクロールはないし、カスタマイズするアプリにもないのだが、他のアプリでShiftキーを押したままホイール回転させることで代用できるものがあるらしい。
今のところ必要に駆られていないので、そういうときはマウスを使うことにしよう。


肝心の使い勝手だが、まだ思った位置にカーソルを動かすことはできないものの、素早い移動はしやすい。
一番難しいのは、ドラッグだ。
まあ、これもやっていれば慣れるんじゃなかろうか。

期待した方向に動かすことができないというのが、慣れの問題なのか、そうでないのか。。。
上下に動かしているつもりでも、ボールを動かす量が多いとぶれてしまうのだ。
ブラウザのマウスゼスチャーなんかは、あんまりうまくできていない。


このままトラックボールでいくか、マウスに戻るのかはわからないけど、もうしばらく使っていてもよいと思った。
とにかくよいのは、指の関節をあまり使わなくて済むところだ。
うまくいけば腱鞘炎対策になりそうだし、そうでなくても腱鞘炎になったらマウスからトラックボールにする、という選択肢が増える。

2017/10/14

[c/c++]16bit→32bitへの拡張は行われるが、32bit→64bitへの拡張は自動で行われない

ミスった・・・。

Windows 10 64bit(Bash on Ubuntu on Windows)
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5)

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    int32_t  a = -1;
    uint32_t b =  1;
    if (a < b) {
        printf("OK\n");
    } else {
        printf("NG\n");
    }
}


私は、符号違いのために64bitまで自動で拡張されてOKルートを通ると考えていたのだ。
たぶん、過去にも同じような記事を書いていたと思うが、そうではなくNGルートを通った。
変数が32bitではなく、16bitであればOKルートを通る。


『Cクイックリファレンス』のp.48に、同じような例が書かれていた。
まず、-1の方がuint32_tに変換されるのだ。
もちろん、明示的にint64_tに変換すればOKルートを通るのだ。


符号の有無が異なるところは、明示的にキャストした方が無難だな。
昔はコンパイラでwarningが出ていたような気がするけど、-Wallしても出ないんだよなぁ。
-Wだけの方がよいかもしれん。

2017/10/13

[git]間違ってcommitしてpushまでしてしまっても怒らない

ぼーっとしていると、gitの操作を間違うことがある。

昨日は、branchを作るのを忘れたまま作業してしまい、そのままcommitし、pushまでしてしまったのだ。
自分しか使っていないのでなんとでもなるのだが、あまり気持ちがよいものではない。


pushする前であればresetでもやるとよかろうが、pushしてしまうと、できないことはないらしいが、取り消さない方が良いそうだ。
まあ、そういう気はするな。

しかし、それをやってしまうことはあるだろうから、グループ内で運用する場合であっても怒らないような文化にした方がよいだろう。
やってしまいがちな操作を禁止して、やらかしたら怒る、というやり方は萎縮させてしまうだけだと思うので、手順を決めておきたい。


結局、こうやった。

  1. やってしまったcommitをrevertで戻す
  2. その状態でpush
  3. ブランチを新しく作って移動
  4. 1のrevertをrevert
  5. その状態でpush

どうせpushするつもりだったんだから、もうそれでいいや、という運用だ。

commit履歴のコメントが「最初のコメント」「Revert 最初のコメント」「Revert Revert 最初のコメント」と並んでしまうのだが、やらかしたんだな、くらいでスルーしてしまえばよい。


しかし、コメントに「Revert」と入るだけだったら、本当にRevertしたのか、コメントの文字列に書いただけなのか区別できん気がするのだけど、そこまで管理してるのかな?

[btc]bitFlyerのP2WSHアドレス

さっき、bitFlyerからメールが来た。
私はbitFlyerにアカウントを作っているので、アナウンスがあるとメールが送られてくるのだ。


いつも bitFlyer をご利用いただきありがとうございます。 P2WSH 方式の Segwit に対応いたしましたのでお知らせいたします。
 
【P2WSH 方式の Segwit に対応】
お客様が bitFlyer アカウントからビットコインを外部のビットコイン・アドレスへ送付する際のトランザクションを P2WSH(Pay to Witness Script Hash)方式の Segwit に対応しました。当社が世界初*で採用した P2WSH は数ある Segwit の実装方式で安全性及び技術的難易度が高いもので、アドレスが「bc1」で始まることが特徴です。


ほー。


この話は、BIP141と、BIP173に関連したものだ。


まず、「P2WSH方式のSegwit」から。

今のところ、Segwitの表現方法は4つある。
https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#examples

  • P2WPKH
  • P2WPKH nested in BIP16 P2SH
  • P2WSH
  • P2WSH nested in BIP16 P2SH

P2PKHのSegwit版がP2WPKH、P2SHのSegwit版がP2WSHと、名前に「W」が入る。
それに「nested in BIP16 P2SH」が付くかどうかだ。

P2SHというのは、「マルチシグ」が代表格で、複数の人が署名するようなタイプのアドレスだったり、個人じゃなくてスクリプトに署名したり、するタイプのアドレスだ。
個人向けの非SegwitアドレスがP2PKHで、そうじゃなく非SegwitアドレスがP2SHと思っておけばよいかな。


Segwitは、アドレスの方式ではなく、トランザクションの構成などを表すもの。
トランザクションの構成が違うから、アドレスも区別できるようにした、というところかな。

しかし、いきなり「明日からSegwitのアドレスだけにします」と言われても、他のアプリは急に対応できない。
だから、まずは純粋なSegwitのトランザクションではなく、P2SHの皮をかぶせたSegwitトランザクションを作ろう、ということになったんじゃなかろうか。
経緯は知らないが、構成としてはそうなっている。
それが「nested in BIP16 P2SH」とついているタイプのアドレスだ。

アドレスを見ただけでは、それがP2SHなのか、Segwitのnested in BIP16 P2SHなのかは区別が付かない。
区別が付かないから、従来のアプリもP2SHとして処理できる、というわけだ。


ただ、皮をかぶせている分、トランザクションのサイズは大きくなっている。
トランザクションのサイズが大きくなると、手数料に反映されてしまう(基本的に、トランザクションのバイト数で手数料が決まるので)。
だから、どこかでnested inじゃないアドレスを作って普及させねば、という課題があったのだろう。
そこで出てきたのが、BIP173だ。


今までのP2PKHやP2SHのアドレスは、秘密鍵にハッシュ計算を何回か行って作り出すものだ。
BIP173で使うBech32という方式?はそれとは異なる。
どう異なるかは、ここで書くにはとても足りないので、BIPを読んでほしい。
けっして、けっして私が理解できなかったわけではないぞ。。。。

BIPに、アドレスの例が載っている。
https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#examples

価値がある方のblockchainであるmainnetで使えるアドレスは「bc1」で始まっているのが分かるだろう。
bitFlyerのメールだけでは詳細が書かれていなかったのだが、たぶん、これを指しているのだと思う。

BitcoinのMainnetは「bc」、Testnetは「tb」で始まる。
これが「Human Readable Part」と呼ばれる部分だ。
まあ、直訳すれば、人間が読める部分、だな。

その次の「1」は単なるセパレータで、それから後ろが実際のデータ部になる。


Bech32になると、QRコードなんかで表現しやすいらしい。
だからというわけでもないけど、そのうちアドレスはBech32がメインになっていくのかもしれんね。

私ももうちょっと勉強しよう。
リファレンス実装があったので、仕様をよく読まずにC言語でmainnetとtestnetに限定したバージョンを作ったのだけど、regtestのことは考慮になくてね・・・。

2017/10/12

[btc]systemctlでbitcoindを起動させておく

当たり前だが、bitcoindは起動していない間はblockchainの同期を行ってくれない。
testnetしか使わない私だが、作業するたびに同期時間がかかるのは嫌なので、VMを立ち上げたときは起動したままにしているし、クラウド上のものもそうしている。

ただ、Linux自体を再起動したときに起動し忘れることが多々ある。
うちではUbuntuを使っていて、serviceよりもsystemctlを使うような感じがしたので、メモを残しておく。


Sample init scripts and service configuration for bitcoind

bitcoindのgithubに、簡単な説明が書かれているので、基本的にはこれに従う。


説明では、データを/var/lib/bitcoindに置くようだが、既に運用しているデータフォルダがあるし、ユーザも1人しかいないので、そっちを使い回すことにする。

systemdの場合はここに書いてあったが、Ubuntu16.02には /usr/lib/systemd/system というディレクトリが無かった。
作るほどでもないと思うので、 /etc/systemd/system に bitcoind.serviceというファイルを置いた。
個人のものをsystemd/systemに置くのもどうかと思うが、一人だと迷惑はかからんだろう。


ファイルの中身も、githubにサンプルが上がっている。
bitcoin/bitcoind.service at master · bitcoin/bitcoin

PIDは何番でもいいし、wallet機能はいるし、さっき書いたようにユーザも固定したいのでそこら辺だけ変更している。
UserとGroupが個人のもので、今運用しているのだったら、ExecStartは「/usr/bin/bitcoind -daemon」くらいで済んでしまう。

他の設定は、変更してもよいのだろうけど、このままでも困りそうにないので残した。


あとは、これだけやれば起動した。

$ sudo systemctl enable bitcoind.service
$ sudo systemctl start bitcoind.service

reloadするようなコマンドを打たないとダメだったような気がするのだけど、動いてるな・・・。
まあ、reloadせんといかんときはメッセージが出てきた気がするので、それに従えばいいんじゃなかろうかね。

2017/10/11

[c/c++]gccの-Dオプションで文字列を指定する

以前、INIファイル形式を読込みたいので、ライブラリを使った記事を書いた。

コメントとして「#」を許容させるためにあれこれやっていたのだが、ソースを見ると行頭の「;」と「#」はコメント扱いのようだ。。。
https://github.com/benhoyt/inih/blob/master/ini.c#L125

マクロの「INI_INLINE_COMMENT_PREFIXES」は、インラインだから、行の途中で見つかった場合にコメントとする文字のようだ。


前回はMakefile自体を変更したが、よそのgithubに入っているMakefileを変更するのは避けたい。
そういうときは変数が使えるようになっていると、なんとかできる。
inihでは「EXTRACCFLAGS」が外部用に用意されているようだった。

$ EXTRACCFLAGS="-g -O2 -D'INI_INLINE_COMMENT_PREFIXES=\"#\"' -DINI_STOP_ON_FIRST_ERROR=1" make -f Makefile.static

文字列は、シングルクオーテーションで囲むのがよさそうだった。
Makefile中ではないので、#をエスケープしなくても大丈夫だ。


シングルクオーテーションで囲むのは、-Dで関数マクロ形式を指定する場合の説明に載っていたやり方を真似しただけなので、もしかしたら文字列はもっと簡単なやり方があるのかもしれん。

2017/10/09

[zybo]これまでの復習

久しぶりにZyboを触ろうとしたが、どういうものだったか、何を調べてきたのかすら記憶に残っていないので、復習しておこう。



まず、CPU?として、XilinxのZYNQ-7000シリーズである、Z-7010が搭載されている。
PS部としてARM Cortex-A9(650MHz)が2つ。
PL部として7-series Artix FPGA相当のものが搭載されている。

PS部とPL部は、EMIO, AMBAなどのバスでつながっているようだ。


ARMのA9が載るだけあって、周辺も充実している。
RJ45もあるし、HDMI(I/O)、Dsub9のVGA、MIC IN, LINE, INもあるし、タクトスイッチやスライドスイッチ、GPIOのポート(Pmod)もある。
USBは、Type-Aもあるし、microBを使えばFTDIが載っているのでUSBシリアル変換でコンソールとして使うこともできる。

microSDカードもささり、そこから起動させるようなこともできるのだ。


なかなかよいのだが、発売がもう3年くらい前になるためか、情報があまり更新されていない。
FPGAの勉強用であれば、もうちょっと最近発売されているボードの方がおすすめだと思う。

Xilinxが発売しているボードであれば、Vivadoなどの開発環境で最初から設定が入っていそうだから、本筋にすぐ入っていけるのではなかろうか。
私なんか、おかげで、新しいPetaLinux(Xilinxが提供しているLinux環境)をZyboで動かすために数ヶ月かかってしまったぞ。

まあ、それはそれで勉強になってよいのだけどね。


おかげで、まだVHDLとかVerilogとかにはほとんど手を出していない。


FPGAというと、なんとなく組込みジャンルで考えていたのだが、ZyboみたいにOSが載る環境で使えてしまうと、もっと違う使い方をした方がよいような気がしてくる。

もちろん機器の制御もできるけれども、ハードウェアに近い部分でロジックを作ることもできるのだ。
そうなると、柔軟な並列演算処理装置、という見方もできよう。
GPUで仮想通貨のマイニングしたり、ディープラーニングの演算をさせたりするような、そんなイメージだ。

私はCortex-M系のマイコンを使うことが多かったのだが、A系だと電池で動かすこともないだろうし、動作クロックもそうとう高い。
Linuxを載せたとしたら、デバイスの制御にはデバイスドライバを介することになるだろう。
割り込み処理ですれスケジューリングされてしまうはずだ。


そうなると、少々のことであればPL部を使う必要がないはず。
PS部からGPIOで制御した方が、自由がききやすいと思う。
そうなっていないということは、A9とOSが載った環境ですら難しいことをPL部にやってもらうのがよいのではなかろうか。

ということで、結果的に「FPGAのFPGAっぽい部分をがんばるべし」という結論になった。
何をがんばればよいのかわからんけど、GPIOみたいなものの制御ではなく、並列でロジックを書けるようになるとか、そういう方向がよいのかな?

[xilinx]SDx 2017.2が出ていた

3連休なので、FPGAのことをやることにした。

最後にFPGA関連で更新したのがは、PetaLinuxをPC-Linuxでビルドする話の最終回で、ちょうど1ヶ月前(2017/09/09)だった。
あれからVivadoなども起動せずにいたのだが、今日Xilinx Information Centerを起動すると、SDx 2017.2が出ていた。
リリース日が09/05になっているから、単に私が見逃していただけのようだ。

image

Xilinxのすごいところは、リリースノート(pdf)なんかも日本語版を用意するところだ。
過去の分から作りやすいだけなのかもしれないが、いやいや、すごいもんですよ。


さて、いまSDxをインストールしているのだが、これにはVivado 2017.2も含んでいる。
使ったこと無いけど、Vivado HLSも含んでいる。
リリースノートからすると、XSDKに入っているのと同じARMのToolchainを含んでいるそうだ。
だから、XSDKでできることがSDxでもできるのであれば、SDxだけあればよいはずだ。


SDxがインストールできるのは、Zybo購入時にSDSoCのライセンスを購入しているからだ。
つまり、WebPACKではないので、WebTalkをオフにすることができる。
まあ、仕事で使っているわけでも無いし、変な動作をしないなら気にしないのだけどね。


あとは、私がこれらを使いこなせるかどうかなのだが・・・まだ全然ダメだ。
まずは、LED以外のチュートリアルを動かして遊んでみよう。


SDxでインストールされたVivadoを起動すると、ウィンドウの名前は「Vivado 2017.2_sdx」という名前になっていた。
微妙に違いがあるのかもしれん。

Vivado 2017.2で使ったことのあるプロジェクトがRecentとして出てきたので、そこら辺は共通なのか。
ただ、IPのリビジョンが微妙に上がっていたようで、そこはUpgradeした(プロジェクトをVivado 2017.1で作ったままだったかもしれない)。


Upgradeしたあとは、Bitstreamを作り直す。
プログレスを示すくるくるが出てくるようになった。
できれば、右下に出てくるか、最小化しないようにできるとありがたいのだが、まあぜいたくは言うまい。

いまRunning synth_designが実行されているようなのだが、とても長い。。。
そんなにPCの性能は悪くないと思うのだが、うたた寝しても良いくらいの時間はかかっているだろう。

ようやく終わって、Exportしなおして、Launch SDKすると、SDxが起動した。
以前、XSDKで作っていたプロジェクトが表示されている。


ということは、SDxがインストールされていれば、VivadoとXSDKは個別にインストールしなくてよいということになるな。


ついでに、SDxのチュートリアルをやっておこう。
SDxのリリースノートから、ug1028-sdsoc-intro-tutorial.pdfというSDSoC環境チュートリアルがたどれたのだ。

チュートリアルをやりたいというよりは、SDxでZyboを使ったデバッグができるのかを試したかったので「6.デバッグ」だけにする。


説明はZC702ボードになっているが、Zynq-7000デバイスであればよいらしい。
Zyboはそうなので、動くのだろう。
スタンドアロンアプリケーションをダウンロードして実行するところまで行えるそうだ。

ボードの設定は、SDカードがどうのこうの書かれているが、microUSBで電源とUARTを確保し、起動モードはJTAGにした。
以前System Debugをした感じからすると、他のモードでも動くんじゃないかと思うが、演習に関係するところだけ確認させたいのでそうしているようだ。


次は、スタンドアロンプロジェクトの作成。
書いてあるとおりにやっていくだけだ。
最後に「Build Project」するのだが、これが重くて長い。。。
15分以上やっているが、まだ25%だ。

結局、26分くらいかかりました。

image

すごいスペックというわけではないけど、けっこうよいスペックじゃないかと思うのだが、どうだろうか。
ウイルス対策ソフトがDefenderなので、そこで時間かかったりするのかもしれん。


デバッグは、Eclipseでデバッグするときの要領でよいが、選択するのは「Launch on Hardware(SDSoC Debugger)」だ。
似たような項目がたくさんあるので、赤文字のところを気にしておこう。
選択すると、パースペクティブを変更するか聞いてくるので、Debugに切り替える。
そうすると、mainで止まった状態が表示される。

ZyboのUARTというかシリアルポートというか、それをターミナルにつないでおく。
私はTeraTermにした。


ブレークポイントで止まった状態なので、再開アイコンをクリックする。
そうすると、ターミナルに何か出てきて、SDxの方は_exitで停止した。
ブレークポイント一覧を見ると、mainと_exitに設定されていたので、これでよいようだ。

Testing 1024 iterations of 32x32 inting point mmultadd...
Average number of CPU cycles running mmultadd in software: 1145442
Average number of CPU cycles running mmultadd in hardware: 19192
Speed up: 59.6833
TEST PASSED


何をやったのかはわからんが、行列演算で使いそうな計算をPL側に持っていったことで高速化したとか、そんな感じではなかろうか。
まったくVivadoに触ってないし、FPGA Programなんかもやっていないから、うまいこと使いこなせると私のようなソフト屋さんには便利そうだ。

2017/10/07

jqコマンド

最近、JSON-RPCで指示を出して、その結果を取得するようなプログラムを作った。
ネットでよくある、JSON整形してくれるページで結果を確認したので、まあ間違ってはいないようだ。


JSON形式は、あまりお好きではない。
理由は、コンマだ・・・。

最後のデータにコンマを許可しないというルール故に、出力するときはひどく面倒なのだ。
まず、1行目の先頭にコンマがあってはならないので、1行目は普通に出力する。
2行目があるなら、コンマを出力してから2行目を出力することになる。
そして、それを繰り返していき、最後のデータの場合はコンマ無しで終わらせる。


順番にデータを掃き出すときはそこまで困らないのだが、嫌なのはforなどでぐるぐると掃き出したい場合だ。
コンマを出力する処理を、行の出力を行う前に置くか、後に置くか。。。
前に置くと、1行目だけコンマ出力をスキップする、という処理がいるし、後に置くと「次のデータがあるか」をチェックする処理がいる。
それが嫌だったら、1行目の出力と2行目以降の出力を分け、forですぐにコンマ出力するようにしておけばよいが、コンマのためだけに処理を分けるのも腹立たしい。

最後のデータにコンマを許可するか、あるいはコンマを無くしてしまう構造だったら悩まなくて済むと思うのだ。
まあ、データ構造に文句を言っても仕方ないのだが・・・。


JSON形式で出力するのが面倒であることを書きたいだけの記事なのだが、それだけでは何なのでjqコマンドのことを書こう。

Ubuntuではapt-getでinstallすることになるが、jqというJSON形式のデータを整形したり加工したりできるコマンドがある。
非常に多機能なのだが、自作で掃き出したJSON形式の改行やスペースが見づらかったとしても、引数無しでjqコマンドを通すだけで見やすくなる。

$ ./cli/lightning-cli getinfo
{ "id" : "02d030cf51591116155597cee2cbf8bb432fa01b691c055d329b51c838fd754130", "port" : 9735, "network" : "testnet", "version" : "v0.5.2-2016-11-21-964-geedbd1d", "blockheight" : 1209621 }


$ ./cli/lightning-cli getinfo | jq
{
   "id": "02d030cf51591116155597cee2cbf8bb432fa01b691c055d329b51c838fd754130",
   "port": 9735,
   "network": "testnet",
   "version": "v0.5.2-2016-11-21-964-geedbd1d",
   "blockheight": 1209621
}

ほら、この通り!
カラーが使えるコンソールであれば、パラメータとデータで色分けもしてくれるし、データも数値か文字列かで色が変わってくれるので、見やすい。


いま見ているgithubのサイトで、よくわからない使い方をしているので、なにやっているのか見ておきたい。

https://github.com/ElementsProject/lightning#receiving-and-receiving-payments

route=$(cli/lightning-cli getroute <recipient_id> <amount> 1 | jq --raw-output .route -)

cli/lightning-cliコマンドが何を出力するのかはあまり関係ないのだが、例がないと分かりづらいので載せておこう。

{ "route" :
         [
                 { "id" : "aaa", "channel" : "1207790:27:0", "msatoshi" : 101023561, "delay" : 92 },
                 { "id" : "bbb", "channel" : "1207703:21:0", "msatoshi" : 100511006, "delay" : 56 },
                 { "id" : "ccc", "channel" : "1207785:11:0", "msatoshi" : 100001001, "delay" : 46 },
                 { "id" : "ddd", "channel" : "1207779:2:0", "msatoshi" : 100000000, "delay" : 36 } ] }

コマンドの1行としては、「route=$(中身)」が外側で、その中身がjqの結果になるのだと思う。
では、cli/lightning-cliコマンドが出力した内容をjj.txtというファイルに保存したとすると、こうなるはず。
青文字が結果だ。

$ cat jj.txt | jq --raw-output .route-
[
   {
     "id": "aaa",
     "channel": "1207790:27:0",
     "msatoshi": 101023561,
     "delay": 92
   },
   {
     "id": "bbb",
     "channel": "1207703:21:0",
     "msatoshi": 100511006,
     "delay": 56
   },
   {
     "id": "ccc",
     "channel": "1207785:11:0",
     "msatoshi": 100001001,
     "delay": 46
   },
   {
     "id": "ddd",
     "channel": "1207779:2:0",
     "msatoshi": 100000000,
     "delay": 36
   }
]

「route」要素だけを出力したことになるのかな?
ただ、これを環境変数?に代入して、echoなどで掃き出しても、改行が残らないのだ。

$ route=$(cat jj.txt | jq --raw-output .route -)
$ echo $route
[ { "id": "aaa", "channel": "1207790:27:0", "msatoshi": 101023561, "delay": 92 }, { "id": "bbb", "channel": "1207703:21:0", "msatoshi": 100511006, "delay": 56 }, { "id": "ccc", "channel": "1207785:11:0", "msatoshi": 100001001, "delay": 46 }, { "id": "ddd", "channel": "1207779:2:0", "msatoshi": 100000000, "delay": 36 } ]

最後のハイフンがそういう意味なのかと思ったけど、ハイフンを外しても結果が変わらんかった。
tarコマンドで、標準出力とか標準入力とかを使うときにハイフンを付けるのと同じ意味のように思う。
じゃあ、パイプじゃなくてもいいやん、というか、パイプで書いているからハイフンがなくても動いているのかもしれん。


とにかく、何が言いたかったかというと、バイナリデータ最高!、ということでした。。。

2017/10/06

AzureでVM作った後にNSGを変更する

まったくの個人メモです。

Azureの使い方がよくわかってないけど、がんばってVMをたくさん作った後で、設定するネットワークセキュリティグループを間違えていたのに気付いたときの変更方法。



  1. 変更したいVMをクリック
  2. 左から「ネットワーク」をクリック
  3. 上に出ているネットワークインターフェイスをクリック
  4. 左から「ネットワークセキュリティグループ」をクリック
  5. 上の「編集」をクリック
  6. 現在のネットワークセキュリティグループが表示されるので、クリックし、気に入ったものをクリック
  7. 上の「保存」をクリック


ネットワークインターフェイス名が分かっているなら、リソース一覧から選択した方が早いな。

2017/10/05

[md]markdownで改行しようとスペース2つ付けたらMD009

Visual Studio Codeをしばしば使っている。

markdownに便利なExtensionsもあるので、適当にインストールしているのだが、それからLINTのようなものが働いて動的に指摘が入るようになった。
あまり慣れていないので助かる。

指摘と言っても、エラーになるわけではないから、無視してもよい。
pyCharmでpythonを書いたときに指摘されるような、あんな感じだ。


指摘を見ていると、改行しようとして行末にスペースを2つ入れているところに何か出ていた。

image

スペースをつなげるなって?
でも、markdownの改行は、行末にスペース2つじゃなかったっけ。。。


https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md009
https://github.com/markdownlint/markdownlint/blob/master/docs/RULES.md#md009---trailing-spaces

改行についてはbr_spacesというオプションで指定することで回避できそうだが、デフォルトは0だし、vscodeのオプションにはそれっぽいものが出てこなかった。
今回は、MD009はfalse設定にすることで、見過ごすことにしよう。。。


デフォルトが0ということは、markdownの改行はあまりやらないのか、他の手段を使っているということなのか。
英語だと、段落になるまでずらずらつなげて書くのかもしれないけど、日本語だと「ここで別の行にしたいが、段落を変えたいわけではない」ということがあると思うので、そういう違いなのかもしれん。

2017/10/02

[c++]boost::tie ?

前にboostを使って最短経路を求める(1,2,3,4,5)というのをやった。
そのときは目的を達成できてよかったのだが、今になってよくわかっていないところがあることに気付いた。

サンプルソースのここで並び替えを行っているのだが、本業ではこの箇所で辺(edge)に載っているデータを使って計算するようにしていた。

bool found;
graph_t::edge_descriptor e; boost::tie(e, found) = edge(v, p[v], g);

これで、foundがtrueになれば、該当するedgeの番号がeに入ったことになるらしい。

しかし、別の箇所では

boost::tie(e1, inserted) = boost::add_edge(v1, v2, graph);

などとしている。

単に戻り値をeやe1に入れるだけなら、boost::tieなどいらないはずだ。
そもそも、boost::tieってなんだ??


http://www.boost.org/doc/libs/1_65_1/libs/tuple/doc/tuple_users_guide.html

tupleは要素数固定のデータ集、でよいのかな?
そして、tieはtupleだけど要素が固定値ではないもの・・・?


std::pairは2つ限定だし、std::tupleはC++11からのようだから、boostにあったtupleがC++11に入ったのかな?
よく見ると、std::tieもC++11にあるそうだ。
boostのtieとstdのtieは同じものだろうか?

いろいろ疑問はあるが、今回はboost::tieの使い方を知りたいだけだ。
消極的だが、やむを得ん。


int i; char c; double d; 
tie(i, c, d) = make_tuple(1,'a', 5.5);

左辺にtieを置いても、ちゃんと使えるようだ。

ということは、最初に挙げた例のfoundやinsertedも、単に変数として使っているだけか。

いや、この引数がboost::tie::inserted、みたいな役割を持っていて、それによって何か結果が変わってくるんじゃないかと心配していたのだ。
自分でbool変数を作っているのだし、それはないか。


これで終わらせようとしたが、さすがにサンプルコードくらいは書かねばなるまい。

/*
 * $ g++ -o tst tietie.cpp
 */
#include <iostream>
#include "boost/tuple/tuple.hpp"

int main(void)
{
    int a;
    std::string b;
    boost::tie(a, b) = boost::make_tuple(123, "yoshio");
    std::cout << a << ", " << b << std::endl;
    return 0;
}

123, yoshio


まあ、そのまんまですな。。。

なんというか、局所的な構造体っぽい使い方ができるのかな?
ただ、戻り値を構造体にするとなると、構造体を定義して、実装側と使う人がincludeなどで共通の構造体を使わないといかんけど、tieだと型と順番が揃っていればよい。

けど、だったら構造体でもいいんじゃないの、という気がするが、構造体が増えていくのも面倒な気がする。
型は同じだけど用途が異なるので、中身が同じ構造体を別に用意する、みたいなことはしなくてよいか。


なんとなく、gcc -Sでアセンブラ展開すると、700行近くなった。
試しに、2行追加してみる。

/*
 * $ g++ -o tst tietie.cpp
 */
#include <iostream>
#include "boost/tuple/tuple.hpp"

int main(void)
{
    int a;
    std::string b;
    boost::tie(a, b) = boost::make_tuple(123, "yoshio");
    std::cout << a << ", " << b << std::endl;

    boost::tie(b, a) = boost::make_tuple("yoshio", 123);
    std::cout << a << ", " << b << std::endl;

    return 0;
}

これをアセンブラ展開すると、1200行ちょっとになる。
順番が違うから、それに応じたコードを生成するしかないのか。


では、同じtieの並びで変数が違ったらどうなる?

/*
 * $ g++ -o tst tietie.cpp
 */
#include <iostream>
#include "boost/tuple/tuple.hpp"

int main(void)
{
    int a;
    std::string b;
    boost::tie(a, b) = boost::make_tuple(123, "yoshio");
    std::cout << a << ", " << b << std::endl;

    int m;
    std::string n;
    boost::tie(m, n) = boost::make_tuple(123, "yoshio");
    std::cout << a << ", " << b << std::endl;

    return 0;
}

これは、750行程度だった。

変数mを、int型からuint8_t型に変更すると、972行。
uint64_tにしても同じだった。

C++のテンプレートは、基本的にマクロの拡張のようなものだったと思うので、uint8_tはint内に収まるから、途中は全部int型で処理して最後にキャストしてやろう、みたいなことはできないのだろう。

まあ、今回は最適化したわけでもないし、アセンブラにして眺めただけなので、違いは出てくるかもしれんが、コードサイズが大きくなることを心配するのであれば、そこら辺は実装側で気をつけねばならんだろうな。

2017/09/29

[btc]bitcoinはあやしいのか、という話はあまり意味が無いと思う

正直なところ、どうでもよい話なのだが、ネタが無いので。

Googleニュースで、キーワードを設定しておくと適当に拾ってきてくれる。
「bitcoin」「blockchain」などのキーワードを設定していると、それなりにニュース記事を拾ってきてくれるようだ。
比較的新しいけど、最新というわけでもないから、閲覧されている順番とか、そんな順かもしれない。

ニュースの内容は、だいたいこういう感じだろうか。

  • どこかが実証実験した
  • どこかがブロックチェーンで何かすることにした
  • 仮想通貨に関する誰かの意見

意見の記事は、かなりの確率で仮想通貨に否定的な内容だ。
あやしいとか、バブルだとか、信用ならないとか、バブルだとか・・・。


まあ、気持ちはよくわかる。

その方面の技術の人じゃなかったら内容を判断することができないので、投資・投機だけやっている人は困るだろう。
今までの知識が役に立たないとき、だいたいは拒否する方を選ぶものだ。

銀行みたいにお金を取り扱うところは、また訳のわからんものが出て・・・と思うかもしれない。
あまり日本の銀行には技術者が多くないという話を聞くので、技術的に分からなければ遮断する方向に行ってしまうだろう。

逆に、技術の人からすると、価値が上がったり下がったりするのは技術のせいじゃないので、知ったことではないと思う。
私はbitcoinしか見てないので、最近はやりのICOなんかは詳しくないのだが、見る人が見るとあやしいものはわかるんじゃないかと思う。
ソースが公開されていれば内容を調べればよいし、公開していないなら調べようがない、というだけだ。


そういう感じだと思うので、全部に通じているような人じゃなければ、あまり相手にしない方がよいかもしれん、とは思う。
私も技術だけしかわからないので、もうちょっと視野を広げないとなー、という気持ちだけは見せている。


仮想通貨は、株式よりも外貨取引に近いと思う。
ただ、どこかが発行しているものではない、というのが「仮想」なのか。

この部分が「発行しているところがないお金なんて信用できない」と「発行しているところがないので安心」のどちらかになるんじゃなかろうか。
そこに価値を見いだす人は買うだろうし、見いださない人は買わないだろう。
買う人が多いと、需要が増えるから、価値が上がる。


ただ、価値が上がった下がったといっても、技術自体がなくなるわけじゃない。
もし、あれこれあって、bitcoinが使えない状態になってしまったら、面倒だろうけど、別の安定した仮想通貨で技術を延ばすだけだ。
bitcoinはわかりやすくて気に入っているのだが、まだまだ私もこの分野では新米なので、あれこれ学んだ方が良いのかもしれんしね。


ごにょごにょ書いていったが、

  • 全体的に見て、よいと思うのであれば、認めてよいのではないか
  • よくわからないなら、そのまま触らなくても問題ないと思う
  • 金儲けの手段としてしか見ない人がぐいぐい言ってきたら、仮想通貨よりも人格を判断した方がよい

というのが今のところの感想だ。

2017/09/27

[c/c++]メモリリークしていると思うが、どうしたものか

アプリのバージョンアップで変更履歴を見ると、ときどき「メモリリーク修正」みたいなものがある。
メモリリークなんて、最初からがんばればよかろうに・・・と若い頃は思っていた。

というよりも、組込みソフトの場合、動的にメモリを取らず、静的にメモリを確保することが多いので、気にしていなかったのかもしれない。
静的に取ることが多いのは、

  • そもそも動的メモリがない(mallocがないなど)
  • 同時に動的メモリを確保して足りなくなることがあってはいけないので、最初から確保しておく

などという理由なんじゃないかと思う。

私の場合は、mallocが無いので、そもそも動的メモリという選択肢がない、という場合が多かった。
まあ、OSが載ることもほとんど無いしね。


ここ半年くらい、PCのLinuxでソフトを書いている。
もちろん、mallocなんか普通に使える。
同時にメモリを確保して足りなくなるなんてことが、ほぼない。
そもそも、PC Linuxで作ることを前提にしているので、リソースは十分にあるものという仕様になっている。
であれば、動的メモリを使わない必然性がなくなってしまう。


なんとなく気付いたかもしれないが、私は動的メモリが苦手なのだ・・・。
なるべくがんばったので、やったことを書いておこう。


前提として、C言語のみ、だ。


malloc系のAPIとfree()をマクロにした

出落ち感があるが、これに尽きる。

マクロにしておくと、例えばmallocしたところを__FILE__と__LINE__で出すことができる。
inlineにしていても、これはできないと思うのだ。

static変数を使って、通過したカウンタなんかを付けるのもやる。
malloc系でインクリメントして、free()でデクリメント。
全部解放していると思っているところでカウント値を見れば、簡易的なチェックには使える。



valgrindする

してたんだけどねぇ。。。
とにかく、終了するアプリじゃないので、valgrind結果を見るタイミングがない。
unit testのときには使えるのだけど、mallocするタイミングとfreeするタイミングが別々になることが多くなると、unit testでは漏れが確認できない。

というよりも、アプリが終了しないので、動的にチェックできたとしても、今が解放されているべきなのか、そうでなかったらいくつ確保されているべきなのか、というのは状態によって異なるので、結局ログを全部追わないとわからんかったりする。

デストラクタとかガベッジコレクションのある言語が憎たらしくなるのは、こういうときだ。


しかし、もう2017年も後半になってきた。

実は、私が知っている手段以外によいものがあるかもしれない。
それに、オライリーの「Debug Hacks」から読み直すべきかもしれん。
組込みで使えそうなところ以外は読んでいないからだ。

2017/09/20

JavaScriptの整数範囲はJSONに影響するのか?

以前、JSON-RPCをやるのにuint64_t対応したライブラリが見つからない、という話を書いた。

結局、内部でしか使わないからいいや、ということで、jsonrpc-cをforkして、uint64_tにだけ対応させることにした。


それはそれでよいのだけど、世の中にはあるんじゃなかろうかと探していた。
同じ疑問を持つ人がいた。
c++ - Does libjson support 64 bit int types? - Stack Overflow

libjsonは知らんのだが、回答からすると、JavaScriptは内部的に53bitまでの制限があるよ、ということらしい。
ECMAScript仕様のページにリンクが貼られていて、確かにごにょごにょ書かれている。


こちらは、ECMAのJSON仕様(pdf)だ。
ただ、JSONのtext format仕様なので、値の範囲がどうのこうのということは書かれていない。


だから、やはり安全にいくなら、uint64_tは文字列にする方がよいのだろう。
32bitずつにして、上下で表してもよいかもしれんが、とにかく表せないかもしれない書式を使うのは危ないかもしれん。
まあ、そんなことをいえばint64_tだって53bit以上あるのだから同じことか。


それだったら、いっそのこと全部の数字を文字列で表せばいいやん、みたいな気持ちになってしまうので、深追いは止めよう。
大人の対応というのは、最終的に自分への負担が減る対応にするべきなのだ。。。

2017/09/18

[vscode]gdbを使ってみよう(2017/09/18)

コンパイラとしてgcc系のものを使うことが多いので、デバッグもgdb系になる。
が、何十年もやっていながら、未だにgdbに慣れていない。。。

だが、世の中にはGUIで隠してくれるデバッガもある。
dddやinsight、eclipseもプラグインで対応できる。
nRF51をデバッグしていた頃はeclipseを使っていたのだが、起動が重たいので、動かすかどうかをためらうこともあった。

最近、Visual Studio Code(以下、vscode)を使うことが多くなったので、そっちでも同じようなことができそうな気配がする。
まずは、vscodeでgdbを使ったデバッグをしてみよう。


vscodeは更新が多く、また機能をextensionsで実現することも多いため、最新版ではここに書いていることが使えなくなっているかもしれない。

こちらは、2017/08/18に更新されているので、これを眺めながらやっていく。
C++ Programming | Visual Studio Code Docs


ビルドはコマンドラインでやってもよいのだが、せっかくなのでvscodeからやってみよう。
昔やった、lmdbのサンプルコードがあったので、それで試していく。
コード自体はどうでもよいのだが、Hello Worldみたいなサンプルではわかりづらいので、多少込みいったものを選んだだけだ。


サンプルは、こうやってビルドできた。

$ gcc -o tst ex1.c -llmdb -pthread

そのフォルダでvscodeを起動。

$ code .

ファイルで開くとダメそうな気がするので、ディレクトリ指定で開くとよいかもしれん。
その状態で Ctrl+Shift+B を押すと、タスクがないよ、というメッセージが出てくる。
「Configure Build Task」の方をクリックすると、4択になるので「Others」を選択。
すると、.vscode/tasks.jsonというディレクトリとファイルを作ってくれる。

tasks.jsonは、こんな感じで書く。

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "taskName": "gcc",
            "type": "shell",
            "command": "gcc -Wall -ggdb -o tst ${relativeFile} -llmdb -pthread",
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": {
                "owner": "c",
                "pattern":[
                    {
                        "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                        "file": 1,
                        "line": 2,
                        "column": 3,
                        "severity": 4,
                        "message": 5
                    }
                ]
            }
        }
    ]
}

リンク先よりもversionが上がっているので、変わりやすいのかもしれん。


"group"を書いて、"kind"を"build"にしないと、Ctrl+Shift+Bでビルドしてくれなかった。
"problemMatcher"を書いておくと、それに引っかかった出力がタブ「PROBLEMS」に出てくれる。
${file}だとフルパスになるためか、PROBLEMSをクリックしてもファイルがないと言われてしまった。
${relativeFile}だとvscodeを開いたディレクトリからの相対パスになるようで、そっちだとOKだった。


makeしたい場合は、こんな感じで書いた。

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "taskName": "make",
            "type": "shell",
            "command": "make",
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": {
                "owner": "c",
                "pattern":[
                    {
                        "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                        "file": 1,
                        "line": 2,
                        "column": 3,
                        "severity": 4,
                        "message": 5
                    }
                ]
            }
        }
    ]
}

ただ、これは統合開発環境じゃないから仕方ないのだが、problemMatcherは出力をなぞるだけのため、Makefile内でディレクトリ移動してMakefileを呼び出す、みたいなことをやっていると、ファイルを見つけられないようだ。

make用のExtensionsがあるのかもしれんが、まあ今回はよかろう。


次はgdb。

https://vscode-doc-jp.github.io/docs/languages/cpp.html#%E3%83%87%E3%83%90%E3%83%83%E3%82%B0
https://code.visualstudio.com/docs/languages/cpp#_debugging-your-code

どっちを見ても、launch.jsonというファイルを作れ、と書いてある。
仕方ないので、.vscodeディレクトリで右クリックし、「New File」でlaunch.jsonを作った。
そうするとlaunch.jsonファイルがタブで開き、右下辺りに「Add Configuration...」というボタンが出てきた。

ボタンを押すと、versionなどのテンプレートが出てきたので、Enterを押して確定。
まだボタンが出ているので押してみると、追加する中身のテンプレートが選べるようだった。
せっかくなので、C++のLaunchするやつを選択。
これはありがたい。


と、ここまでやってリンク先を見たら、Debug Viewにしてやればファイル作成などは勝手にやってくれたみたいだ。。。
悔しいので、.vscode/launch.jsonを消してやり直す。

まず、左側のデバッグっぽいアイコンをクリックし、Debug Viewにする。
設定してくれそうなアイコンが出てくるので、クリック。
そうすると、さっきのような選択が出てくるので、C++のgdbできそうなものを選択。
まあ、できるファイルは同じっぽいな。


"program"は書き換えないといかんだろう。
"${workspaceRoot}/tst"にする。
ファイル保存して、Viewにあるデバッグ開始しそうなアイコンをクリック!

・・・開始エラー?
よくわからんのでもう一度押すと、今度は動いて、設定していたブレークポイントで止まったようだ。
たぶん、launch.jsonの"stopAtEntry"を設定しておくと、その関数で止まるようになってるんじゃなかろうか。


変数名にマウスを当てると中身が見えるし、構造体も出てくれる。
整数型は10進数で、ポインタは16進数で表示するようだ。
16進数で見たい場合は、WATCHとして追加するしかなさそうだ。
例えば、env->me_flagsという値を16進数で見たかったら、「env->me_flags,h」のように指定するそうだ。
https://github.com/Microsoft/vscode-cpptools/issues/379

2016年12月のことだから、今は別の手段があるかもしれん。。。が、それっぽいのは見つからなかった。
まあ、こういうのは、だいたい解決されていくものだし、方法がないわけではないからよかろう。


こんな感じで、gdbを使うだけであればlaunch.jsonを作るだけでよさそうだ。

2017/09/17

[btc]confオプションはフルパスで書くべし

testnetでなかなかマイニングされないので、regtestに切り替えようとしている。
まあ、testnetは有志によるものっぽいから、何が起きても文句は言えない。。。


まず、testnetとregtestを同時に動かしておけるかどうか。
これは、ダメそうだ。
bitcoindがHTTP serverになるようで、2つめを起動したらエラーになった。

Error: Unable to start HTTP server. See debug log for details.

引数で何か設定すればよいのかもしれんが、まあそこまで切実ではないので、よかろう(実はできるのだが、後述)。


次は、confファイル。
bitcoindはデフォルトで~/.bitcoin/bitcoin.confを見に行くが、regtestのために書き換えるのが面倒だから、regtest用のconfファイルを読み込ませたい。

regtest=1
server=1
txindex=1
rpcuser=xxx
rpcpassword=xxxxx
rpcport=18443

こんな感じか。
rpcportを設定したのは、まあ、確認みたいなものだ。

$ bitcoind -conf=./regtest.conf

そして別のコンソールから確認。

$ bitcoin-cli -conf=./regtest.conf getblockcount
74242

ん??
regtestなのにブロックがあるし、やるたびに増えていってるからどこかからダウンロードしているようだぞ。
networkinfoで見ると、やはりピアが見えているし、ポート番号も8333だ。
ということは、mainnetを見に行ってるらしい。


こうやるのがよさそうだ。

$ bitcoind -conf=./regtest.conf -regtest

納得がいかないのだが、仕方ない。

regtest.confから「regtest=1」を削ってもよいかも。
ただ、bitcoin-cliの方は-confで設定したregtestを見ているようで、-regtestオプションを付けなくてもよいようだ。
まあ、bitcoindが付けているのだから、両方付けた方が統一されていてよいかもしれん。


では、最後にJSON-RPC。

$ curl --user xxx:xxxx --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockcount", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:18443/

ダメだ、接続できない。
wiresharkでbitcoin-cliしたときのポートを見ると、18332になってる。
全然confファイルの言うことを聞いてくれんやつだ。。。

そして、ポート番号を18332にしてもダメ。
認証に失敗しているようだから、rpcuserなんかも見てないということか??
しかし、getnetworkinfoで見ると、なんか18444を監視している。
いっちょんいうことばきいてくれんっちゃけんねぇ。。。


このregtest.confを、カレントディレクトリではなく~/.bitcoinの中に置き、-conf=regtest.confとディレクトリ無しにすると、すんなり動く。
-regtestもいらないし、JSON-RPCも書いてある通りの設定になる。
よくわからんが、その方がいろいろやるよりも安全な気がする。


自動実行するときは、systemdに登録しているのだが、そのときはたぶんUserで指定した人の~/.bitcoin/bitcoin.confを使っているのだろう。
ここを見ると、/etc/bitcoin/bitcoin.confを例にしているので、そういうのはありなんだ。。。
https://github.com/bitcoin/bitcoin/blob/master/doc/init.md

systemdのservice設定を見ると、conf指定だが、フルパスで書いているな。
https://github.com/bitcoin/bitcoin/blob/master/contrib/init/bitcoind.service

まさか・・・。

$ bitcoind -conf=`pwd`/regtest.conf

はい、そういうことでした。
confはフルパスで書くべし、でした。

最初に試した、testnetとregtestを同時に動かす、もconfファイルを相対パスで指定していたのでうまく動いていないだけだった。
datadirを別にすれば、regtestを複数立てることもできるんじゃなかろうか。意味はなさそうだがね。

2017/09/16

[bow]lmdbのmdb_env_open()でエラーになる

msg queueを使うプログラムを作っていたのでUbuntu16.04で作業していたのだが、socketに変更したので今のbash on Ubuntu on Windowsでも動かせるようになったんじゃなかろうか、ということでやってみた。

・・・そこに行き着く前に、lmdbのmdb_env_open()でエラーが返ってきた。。。


エラーの内容は、exec format error。
ENOEXECというやつだ。

ずーっとたどると、mmap()でエラーを返しているようだった。
gdbを使わず、printfデバッグで探していたので、たどるのが大変だった・・・。
GUI環境じゃないところで、まだgdbを使えないのだよ、私は。


この辺りかな?
mmap's problem · Issue #658 · Microsoft/BashOnWindows

いろいろ書いてあってよくわからんが、まあ、たぶんbowのバグなんだろう。
2017年秋バージョンに期待だ。

[btc]testnet3

bitcoindでは、ほとんどtestnetを使っている。
bitcoin.confにも「testnet=3」と書いている。

が、btcdなんかは1と書く(3だとエラー)。
つまり、testnetは実質、testnet3しかないというになるだろう。

そもそも、testnet3ってなんだ??


Testnet - Bitcoin Wiki

このページの最終更新日は2017年2月8日なので、新しいといってよいだろう。

testnetには3つあります。

testnet2は、testnetと異なるgenesis blockを持つ最初のtestnet resetだ。
testnet3は、現在のtest networkだ。

2行目の訳が怪しいので、原文を読んでおくれ。
とにかく、初代testnet、testnet2、testnet3があり、今はtestnet3ということだ。

引数だって「-testnet」だし、bitcoin.confが「=1」でも「=3」でも特に動作は変わらないようだ。
bitcoindでも、bool扱いしているように見えるから、0でなければtestnetになるんじゃなかろうかね。

2017/09/14

[tech]IPFS

世の中にはいろいろと技術があり、「これどうやってるんだろう??」というものも多い。
IPFSも、私にとっては「ど、どうやってるんだ??」という技術の一つだ。

なんというか、ブロックチェーンと非常に似たものを感じる。


ブロックチェーンでの開発を行っていると、何かに依存した状況を極力作りたくない。
「ああ、この情報をサーバに置きさえすれば解決するのに・・・」と思ったとしても、それをやってしまうと依存が生じてしまう。
まあ、多少はよいか、という考え方もあるのかもしれないが、やっぱりここまできたらねー、という意地みたいなものも出てくる。


そこで、IPFSだ。
全然技術的に理解はできていないのだが、ファイルをアップロードすると、適当にファイルを分割されて、適当に冗長性を持たせつつ、適当に分散させて、ノードを提供している人たちに持たせている。
たぶん、ブロックチェーンのフルノードみたいに、全員が同じものを持つ、というものではないように思う。
また、単に分割してばらまくわけでもなさそうだ。

それを取得するには、アップロードしたときに渡されるハッシュ値を使う。
ファイル名に相当するのかな。
それを使うと、そのハッシュ値に相当するものがファイルとして取得できるようだ。


サイトにある「Try it」を試しただけで、それ以上は入り込んでいない。
私がやったときは、子猫の画像が取得できた。


まあ、Bitcoinのブロックチェーンだって、こんだけ人々がアクセスしてもハッシュ値でトランザクションが一意に表せているので、IPFSの参加者くらいであれば十分にまかなえているのかもしれないし、ハッシュ値のサイズだって違うかもしれない。

だから、ハッシュ値でファイル名の代わりにする、という考え方はまだわかるのだが、残りの重要な部分はさっぱりわからん。
RAIDみたいな感じを持ってしまうけど、たぶんどこかのIPFSノードが動いていないくらいだったら問題ないんじゃなかろうか。


これは、なんというか、ぞくぞくする怖さを感じましたな。
こういう技術が生まれてくることに、まだまだ視野が狭かったなー、と感じざるを得ない。
いや、自分で生み出せたかも、とかじゃなくて(無理無理...)、世の中で未発見のものは、発見されたとしても私には理解ができないものなんじゃなかろうか、などと考えていたことに対してだ。

一般技術者としては、その発明/発見に敬意を表しつつ、理解し、より使いやすい形にしたり、安全にしたり、応用したりするのがまっとうなやり方かな、と思う。

2017/09/11

[c/c++][linux]stdoutへのリダイレクトが期待通りにできない

共通で使っている処理があり、そこは出力を標準出力に行っている。
ただ、一部だけ、どうしてもファイルに掃き出したいと考えた。
元の方は書き換えたくなかったので、呼び出し元で標準出力をファイルにつなげてやればよいだろう。

この処理は何回も呼び出し、それぞれ別のファイルに出力したい。
だから単純なリダイレクトではないのだけど、まあclose()してやるだけだろう。。。


うまくいかなかった。

リダイレクトを分割したいが、うまくいかない

ファイルは3つできるのだが、中身は3.txtにしか入っていない。
そして、3.txtには全部の出力が入っているのだ。
fdをclose()させていないが、あんまり関係が無かった。

標準出力は出力タイミングまでバッファにためるタイプだったはずなので、SYNCっぽいものをあれこれ追加したのだが、どれもダメだ。


じゃあ、標準エラー出力だったらバッファにためないからいいんじゃなかろうか、ということでやってみると、OKだった。

stderrならうまくいく


ということは、システムコール側ではなく、もっと上位層で制御されているということか。
ならば、ファイルディスクリプタの1をfsync()するのではなく、stdoutの方をfflush()したらいいんじゃなかろうか?

fflush(stdout)するとOK

OKだった。
なるほどねぇ。


ただ、一部だけリダイレクトさせるのも格好が悪いので、結局実装としては別の関数にしてFILE*を取るようにしたのであった。

2017/09/09

[zybo]PetaLinuxでDigilentのチュートリアルが動かん (19) : 完

動かん(18)で、XSDKでRunした場合はZyboのLinuxではなく、素の環境で動いているんじゃないか、という疑惑が発覚した(私の中で)。

素の環境というのは、リセットベクタから起動した後、OSを介さずにC Runtimeだけ動かし、すぐにmain()から動き始める、という意味だ。

バイナリの種類が違いそうだというのは、fileコマンドの結果によるものだ。
PetaLinux用の/bin/bashと比較しよう。


$ file bash
bash: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=bf9ec80803a2f03da139c81eddb5bc276cb5250b, stripped


$ file hello.elf
hello.elf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped


dynamically linkedかstatically linkedだけでは判断できないのだが、「for GNU/Linux」とまで出力されては、違いがあることを認識せざるを得まい。


Windows版のXSDK v2017.2には、どっちのコンパイラもあるようだ。

image

aarch32は、archがARM32bit版の意味かな?
他にもフォルダがあり、aarch64やmicroblazeもある。
こんだけコンパイラがいっぱい入っていれば、ダウンロードサイズも大きくなるわな。。。

単なるarmフォルダもあり、こっちはarm-xilinx-eabiやarm-xilinx-linux-gnueabiもある。

SDK\2017.2\gnu\arm\nt\bin>arm-xilinx-linux-gnueabi-gcc --version
arm-xilinx-linux-gnueabi-gcc (Sourcery CodeBench Lite 2015.05-17) 4.9.2


SDK\2017.2\gnu\aarch32\nt\gcc-arm-linux-gnueabi\bin>arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (Linaro GCC Snapshot 6.2-2016.11) 6.2.1 20161114

ほー。
久しぶりにSourceryという名前を見た。


選択は、プロパティ画面で、「C/C++ Build > Tool Chain Editor」からできそうだった。

image

何も考えずに作ったプロジェクトは、上の図のように選択されていた。
プロジェクトは新規作成したので、どこかで選択できるようになっているはず。

これか。

image

OS Platformがデフォルトで「standalone」になっていたのだ。
これが「linux」ならよいのか。


「linux」にすると、何やら更新が行われ、少し設定項目が変わったようだ。

image

Windowsでやるときも設定できるのだろうか?
そのままウィザードを進めると、テンプレートから空アプリかhelloworldかが選べるので、今回はhelloworldを選択。
自動でビルドしてくれるので、できているELFファイルをSDカードにコピーして、PetaLinux起動。
Zyboで立ち上げて、実行。

・・・動くやん。。。


20回に達する前に解決してよかった、と前向きに考えよう。
長い連載で理解したのはこういうことだ。

  • XSDKでアプリのプロジェクトを作るとき、デフォルトでは「standalone」になっていて、これはOS無しで動くバイナリ
  • OS設定を「Linux」にすると、Windows版のXSDKであってもARM Linuxで動くELFファイルを作ってくれる
  • PetaLinuxのCustom moduleではxparameters.hを読んでくれないので、なんとかせんといかんようだ

なお、どのコンパイラが選択されているかは、XSDKのPreferencesにある「Xilinx SDK > Toolchain Preferences」から確認できそうだ。

image

ZynqはCortex-A9だったと思うので、Linaroがデフォルトのようだ。

[zybo]PetaLinuxでDigilentのチュートリアルが動かん (18)

18回目になるのに、まだ解決しないとは・・・。
いや、そもそも最初の目的はなんだったっけ?

第1回を見ると、Zyboのチュートリアル通りにやってみたものの、EclipseベースのSDKから実行すると動くのだが、実行ファイルをPetaLinux上にコピーして実行してもIllegal Instructionが発生した、ということのようだ。
じゃあPetaLinuxの環境でビルドせんといかんのじゃなかろうか、と。
まずは簡単なものから、と考えて見ていったら、Interface誌にJEポートをGPIO制御するドライバサンプルがあって・・・、というのが、現状だ。


しかし、XSDKのベースとしている環境を変更する、という方向もありかもしれん。
せっかくXSDKがあるのだから、コマンドラインでビルドするPetaLinuxはLinux環境やドライバまでで、アプリはXSDKでやっていきたいではないか。


久々にXSDKを立ち上げ、helloworldアプリをビルドした。
そして、XSDKからRunさせると、ちゃんと"Hello Wrold"がコンソールに出力される。
ここでいうコンソールは、ZyboのUSBをPCに接続して開いたTeraTermのUARTコンソールだ。

そのhello.elfを、ビルドしたPetaLinuxが入っているSDカードにコピーして実行すると、やっぱりIlletal Instructionになる。
Zyboチュートリアルのときは、ハードウェアが関係して、不正なアクセスか何かが発生してダメなのかと思っていたけど、そうではないということか?


まずは、fileコマンドで確認しよう。
PC Linux上で確認する。

$ file hello.elf
hello.elf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

staticリンクだから、ライブラリがないということではないだろう。
まあ、そうだったら別のエラーになるはずだ。


Illegal Instruction | Zedboard

む、「Linux Application」と「Standalone Application」の違いがあるのか。
よく考えれば、XSDKから実行するときは、ZyboにLinuxが立ち上がってなくても動作しているし、XSDKからLinux環境ごと転送して起動させているような様子もない。すぐ実行されるし。

ということは、このELFファイルはLinux環境向けではない・・・?
普通のLinux環境向けバイナリはどうなるんだっけ。。。

$ file /bin/grep
/bin/grep: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=a28bf08898e693819102c974c8e54fdcf6f8a7a6, stripped

ああ、そうなのか。。。
XSDKってなんとなくLinux用のバイナリを作ると考えていたのだけど、よく考えたらFreeRTOSもサポートしているので、素のバイナリも生成することができないといかんのか。


コンパイラ変更とかでよいのかしら?
解決は次回にして、今回はここまでにしよう。

2017/09/08

[btc]TXIDとSegwitのTXIDとWTXID

TXID、というものがある。
Transaction IDの略だ。

IDというと、どこかで管理したりしていそうだが、Bitcoinはどこかに依存することがないというか、全体に依存しているというかで、データのためのデータはそんなにないと思う。

ただ、トランザクションを一意に表す数字がないと不便なのも確か。
だから、トランザクション自体のデータからハッシュ計算してIDを求めている。


さて、Segwitが出る以前。
TXIDはシンプルで、トランザクションデータ全体をSHA256し、それをさらにSHA256した値(32byte)だった。

トランザクションの構成は、こうだ。

  • version
  • txin
  • txout
  • locktime

bitcoindでトランザクションを作ったことがある人はわかるだろうが、順番としては、

  • 署名が空のトランザクションを作る
  • 署名する

という手順を踏む。
署名したトランザクションはブロックチェーンに公開することができるので、署名するのは最後なのだ。
だから、TXIDが計算できるのは署名後ということになる。


さて、時代はSegwit。
Segregated Witnessという名前の通り、署名が分離されたトランザクションになる。
トランザクションから分離したということは・・・TXIDからも分離されたのだ(そういう理屈なのかどうかは、知らん)。

しかし、トランザクションデータには署名が入っている。
細かく言えば、txメッセージで送信するトランザクションデータには署名が載っている。
ではSegwitなトランザクションのTXIDはなんなのかというと、計算方法が以前と異なるのである。
計算式はシンプルなTXID時代からするとかなり面倒になったのだが、署名部分は計算から除外するようになった。

だから、非SegwitトランザクションのTXID計算方法と、SegwitトランザクションのTXID計算方法は異なるのだ。


だいたい話は終わりなのだが、余談としてWTXIDのことも書いておこう。

ずばり、WTXIDは、Segwitトランザクションを以前と同じTXID計算方法で求めた値のことだ。
ただ、WTXIDの使いどころが分からないので、計算をしたことがなく、検証まではできていない。
https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#transaction-id

2017/09/07

[c/c++]JSON-RPCでuint64_tに対応するのは難しいか

最近、サーバ型というかdaemon型というか、バックグラウンドで動くアプリを作っている。
それに対して外部から指示を与えたいことがあるのだが、今までLinuxのメッセージキューを使っていた。
それで困っていなかったのだが、他の類似するツールを見るとJSON-RPCでやりとりしていることが分かった。

長いものに・・・巻かれるしかないのか・・・。

同じ形式でAPIを受け付けるように作っておけば、外側の部分は自分で作らずに済むし、そうしておくことによって他の人から使ってもらえる可能性も上がる(たぶん)。

あきらめて、JSON-RPCのパラメータを受け付けるように改造することにした。


こういうときは、githubなどからライブラリを探して、それを使うのがよいだろう。
Google検索して見つかった一番上が、こちら。

httpの方が汎用性が高いのかもしれないが、TCPのsocketをつくってwrite/read()すれば動くので、作るのが楽そうだ。


半分ほど実装していて思い出したが、今回はuint64_tを使っているのだった。
しかし、この子はintかdoubleしか持っていない。
doubleでは丸められる可能性があって困るのだ。。

そういえば、と別の場所で使っているjanssonも見直してみたが、long long型の対応になっているのでint64_tはいけるものの、uint64_tは無理だろう。

よく考えれば、Cは標準型でそこまでしか対応していないし、JavaみたいにBigDecimalみたいな標準もないため、そもそも対応すること自体が難しいだろう。
janssonのbignum版を作っている人もあったが、整数型はgmpかopensslを使うことになるようだ。
うーん、それはちょっと今回の方針にあわない。。。


今回はintかuint64_tまでしか使わないので、自分でuint64_t対応を追加すればよいのだろうが、気力が湧かない(それでいいのか)。
ひとまず、逃げの手段として、uint64_tは文字列に変換して、読み出すときはまたuint64_tとして戻すことにした。
array型で、順番がこちらで決められるからできる技だ。
ただ、serverもclientも自前じゃないとダメなんだけどね。。。


gccなら__int128があるようで、それならuint64_tのサイズでも収まるから少し気は楽になるが、うーん、やっぱり、なんかねー。
この辺りは、pythonみたいに自由な幅にできる言語が有利ですな。

2017/09/05

[btc]regtestでsegwitするにはブロック数がいる

最近、というわけでもないが、testnetが今ひとつ順調ではないように見える。

数日前は、トランザクションが1つ(というか、coinbaseだけ)のブロックが多く、トランザクションが全然さばけていないようだった。
https://testnet.blockexplorer.com/blocks-date/2017-08-31

今日は普通だと思っていたのだけど、なんかsegwitのトランザクションだけ除外されていないか?
そういう真似ができるのかどうか知らんが、数時間前に発行したsegwitのトランザクションがマイニングされないのに、faucetから送ってもらったトランザクションはすぐにマイニングされていたのだ。


よくわからんが、不安定で作業にならないので、regtestを使うことにした。
初めてのregtestだ。


Bitcoinを使ったアプリケーションのテスト環境 - Develop with pleasure!

bitcoin.confを書き換える程度で動かせた。
regtest時のbitcoin-qtは水色だった。

書いてあるように、bitcoin-cliなどでgenerateコマンドを使うと、その数だけブロックを生成してくれる。
これで、マイニングされたことになるので、ビクビクしなくてよいのだ。


しかし・・・segwitのトランザクションを作ろうとaddwitnessaddressしたのだが、segwitは対応していないとか出てくる。。。
regtestなのに!

検索すると、ちゃんと調べてくれた人が見つかった。
How to activate segwit on regtest

あー、101ブロックしか生成していなかったけど、432ブロック以上ないとsegwitがActiveにならないんだ。
しかし、432ブロックというのはなんだろうか?

https://github.com/bitcoin/bitcoin/blob/28f788e47e58f2b462351d6989348a4e1a241b2b/test/functional/bip68-sequence.py#L371
BIP68関連らしい。

https://github.com/bitcoin/bitcoin/blob/28f788e47e58f2b462351d6989348a4e1a241b2b/test/functional/segwit.py#L198
こちらも432だが、144 * 3ということになっている。

144 = 24(時間) * 60(分) / 10(ブロック毎分)

ということかな?
mainnetの時間で3日分というのが432の根拠のようだ。

なんで3日なのかというのは、わからんかったが、まあいいや。

2017/09/04

[win][修復]Windows10が立ち上がらなくなったので復旧 - 2

まさかの第2弾。
というよりも、OSが立ち上がらないということはしばしばあると思うので、その記録だ。

hiro99ma blog: [win][修復]Windows10が立ち上がらなくなったので復旧


予備で用意しているPCがあり、そのWindows10が起動しなくなった。
用意しているというか、マザーボードやCPUが古くなったので一式買い替えたのだが、その前に使っていたPCだ。
Windowsも新しいPCに持っていこうと思ったのだが、マザーボードが変わるとインストールできないという話を聞いたので、そちらは別途購入したのだ。

最後にWindows Updateしたのが1年くらい前だったので、たぶんその間は起動していないのだと思う。
無事に起動したので、過去のデータはもう不要だろう、とWindowsのリセットで全データ消去を選択。
自動的に再起動してクリーンアップが進んだのだが、途中かどこかでブルースクリーンが発生し、再起動を繰り返すようになってしまったのだ。

クリーンアップしたらきれいな状態で立ち上がるだろう、と思っていたので、修復ディスクは作っていたものの、復旧ディスクは作っていない。
復旧ディスクって、USBメモリ1本使うので、もったいない、と思ったのが正直なところだ。


ブルースクリーンになるのはログイン画面が出る前なのだが、F4を押して起動させるとあのメニューは出てくる。
そこでまたPCのリセットを行ったが、エラーが起きましたというだけで何もできない。
修復ディスクで起動させても、同じようなものだった。

復旧ディスクであれば何でもよいかと思い、ThinkPadで作っていた復旧ディスクで起動したのだが、起動させている間にネットで検索すると、どうも共有できるものではないらしい。
ThinkPadはWin10 Home、予備PCはWin10 Proだったのだが、予備PCにWin10 Homeとかいうパーティションが作られてしまった。。。
もちろん、復旧もできなかった。

このWin10はWin7からのネットワークアップグレードでできているので、Win7のディスクはあるものの、Win10用は何もないのだ。


もうあきらめるしかないかと思ったのだが、もう1つ手段があった。
新しいPC用に買ったWindows10のインストールディスクだ。
これが、使えた。
ディスクから起動すると復旧させるボタンが出てくるのだが、それは押さずに普通のインストールを進める。
プロダクトIDを入力するところをスキップさせると、起動時にネットワーク認証を行うらしい(画面にそう出ていた)。
そうやって進めると、無事に起動できる状態になった。

よかったよかった。
復旧ディスクを急いで作ったのは、言うまでもない。


復旧ディスクって、もうすぐ2017年秋バージョンのリリースが行われるそうなのだが、新しくなるごとに更新した方がよいのだろうか?
そこら辺がよくわからんね。

2017/09/03

[zybo]PetaLinuxでDigilentのチュートリアルが動かん (17)

前回の動かん(16)では、xparameters.hにアドレスの定義が載っていることを確認した。

では、ソースに直接書く方法から、includeして参照する方法に変更しよう。
と書き換えたものの、xparameters.hをincludeしてくれない。。。


xparameters.hは、この2箇所にあるのだが、使うのは前者だ。

components/plnx_workspace/fsbl_bsp/ps7_cortexa9_0/include/xparameters.h
components/plnx_workspace/fsbl_bsp/ps7_cortexa9_0/libsrc/common_v1_00_a/src/xparameters.h


パスを継ぎ足していったのだが、componentsから書いても見つからない。
どこからかの相対パスで指定したいのだが、どこから書いてよいものかもわからん。

あきらめてモジュールのソースファイルと同じ場所にコピーしたのだが、それでもダメだ。
カレントディレクトリすら参照してくれないというのか!


と思ってfindすると、実際にビルドするディレクトリはproject-spec/meta-user/recipes-modules/led8drv/filesではなく、build/tmp/work/plnx_arm-xilinx-linux-gnueabi/led8drv/1.0-r0という場所にファイルをコピーして行っているようだ。
そして、filesにあるファイルをすべてコピーしているわけではなく、xparameters.hなどはコピーされていないため、参照できていない、ということらしい。

じゃあ、何を書き換えたらよいかというと、bbファイルを変更するとコピーしてくれるようだった。

SRC_URI = "file://Makefile \
            file://zybo_gpio.c \
            file://xparameters.h \
            file://xparameters_ps.h \

        file://COPYING \
           "

これで、取りあえずはファイルをコピーしてくれてビルドもできるようにはなった。
だが、ファイルを手動でコピーする手間がかかるし、なにより格好が悪い。


PetaLinux Tools User Guide(UG977 v2014.2)にはpetalinux-configで更新できるようなことが書いてあるのだが、最近ではこのドキュメントは更新していないようだし、やってもダメだった。
きっと、ちゃんとしたやり方があるのだろうとは思うが、わからんのだ。
SDK内であれば何かありそうなのだけど、PetaLinuxのところだけでやりたいのだよなぁ。

2017/09/02

[zybo]PetaLinuxでDigilentのチュートリアルが動かん (16)

久しぶりすぎて、内容を覚えていない・・・。

前回は、GPIOのアドレス定義が自動生成されたxparameters.hに載っていることがわかった、というところまでだった。
何をしていたかというと、Linuxのデバイスドライバを作る際、どのアドレスを操作すればよいのかを調べていたのだ。


今見ているのは、これ。
original: http://www.cqpub.co.jp/interface/download/2016/4/IF1604Z.zip

Interface誌のサンプルをちょっと変更した程度のものだ。
GPIOのアドレスは、gpio_table[]を使っている。

動かん(14)のときにどれを使っているのか計算しているが、mknodしたのが24なのでgpio_table[3]ということだ。
そのアドレスは、0x41200000 + 0x10000 + 0x0。

./components/plnx_workspace/fsbl_bsp/ps7_cortexa9_0/include/xparameters.hを見ると、こういう行があった。

/* Canonical definitions for peripheral BTNS_4BITS */
#define XPAR_GPIO_0_BASEADDR 0x41200000
#define XPAR_GPIO_0_HIGHADDR 0x4120FFFF
#define XPAR_GPIO_0_DEVICE_ID XPAR_BTNS_4BITS_DEVICE_ID
#define XPAR_GPIO_0_INTERRUPT_PRESENT 0

まず、MAP_BASE_ADDRの根拠はわかった。
zybo_gpio.cでは固定値なので、このアドレスも求める方法があるのだろうが、まあ、よかろう。


次はオフセットだ。
制御しているのはZYBOのJEコネクタで、0x41210000から1KBをioremap()し、32bitを書込むようにしている。

ああ、こういう定義が近くにあった。

/* Definitions for peripheral LEDS_4BITS */
#define XPAR_LEDS_4BITS_BASEADDR 0x41210000
#define XPAR_LEDS_4BITS_HIGHADDR 0x4121FFFF
#define XPAR_LEDS_4BITS_DEVICE_ID 1
#define XPAR_LEDS_4BITS_INTERRUPT_PRESENT 0
#define XPAR_LEDS_4BITS_IS_DUAL 0

Block Designを見ると、GPIO類はこうなっていた。

image

この名前が、そのままマクロ定義になるのか。


mknodするminor番号だが、zybo_gpio.cではビットを表していたのか。

0- 7 : ボタン
8-15 : DIPスイッチ
16-23 : 未割り当て
24-31 : LED

だから、16~23だとエラーなのか。
ビットシフトを3つやってるのも、8bit単位で何番目かを割り出すという意味なのだろう。
読み書きの方向についてはminorのb4を使っているが、0~15はINPUTだから使っただけか。
LEDでもスイッチでもいけるように、GPIO_BUFFという構造体を用意して、そこに情報を突っ込み、あとはシステムコールで呼び出されたらそれを使うだけ、ということにしたかったのだろう。


ioremap()は、物理メモリをアクセスする準備みたいなもののようだ。
IoMemoryAccess - Kernel Newbies Japan
MMUもあるし、こういうやり方になるのか。
戻り値をそのまま使ってよいわけではなく、readb/w/l()、writeb/w/l()を介してアクセスするそうだ。
zybo_gpio.cでは iowrite32()を使っているので、ビット幅で指定するタイプもあるのか。

9.4. Using I/O Memory
こちらはオライリーのLinux Deveice Drivers第3版の元ページ?のようだが、readb()などのタイプはolderと書いてある。
まあ、ビット幅の方がわかりやすいわね。


ioremap()だが、終わったらiounmap()しなくてよいのだろうか?
なんとなく、close()時にやった方が良い気がする。

Linuxデバイスドライバのお作法がわかっていないので、基本的なところは抑えた方がよさそうだ。

[c++]Boostのdijkstra_shortest_paths() - end

Boostのグラフで経路を求めたので、最後に、自分であれこれやったソースをGistに置いておこう。

boostのグラフを使って経路探索するサンプル


経路は、boost.jpのグラフにあるものを使った。

$ g++ -o tst dijk_dist.cpp
$ ./tst
distance: 11
START --> Asia --> Beer --> Devel --> Foobar --> GOAL


Boostのサンプルにあった、graphvizで出力するやりかたも真似した。

image

双方向にしたのでゴチャゴチャしているが、方向によって重みが違う場合にはこうやることになるだろう(今回は同じ重みだが)。

[c++]Boostのdijkstra_shortest_paths() - 4

前回は、dijkstra_shortest_paths()に重みを指定しつつ、経路を得るための引数を指定するところまでだった。
なんであんな中途半端で終わらせたかというと、仕事に行く時間だっただけだ。。。

動作結果は、OKだった。
検証したソースを載せたいところだが、そっちは仕事で書いているコードでやってしまったのだ。すまん。


第3引数には他の種類もある。
こちらでは、visitor()というものを使っている。
Boost.Graphに入門 - Faith and Brave - C++で遊ぼう
やっていることは同じような内容なのだが、最短経路以外にも試されている。


BoostのGraphは自由度が高いので、あれこれできてしまい、検索して見たサイトで全部やり方が違っていて「うーん、難しい・・・」と感じてしまう。

ただ、便利だし、Cから使うときもそこだけライブラリにしておけばうまいことやれるんじゃなかろうかと思う。
Makefileで、CとC++を混在させるやり方がよくわからんのだ。。。
.oを.cやら.cppに見立てる方式ではダメだから、最近はソースファイル名を列挙する方式にしているのだけど、extern "C"だけでうまく回避できるんだっけ?


いかんいかん、話が逸れてしまった。
ともかく、BoostのGraphは、大ざっぱに言えば、

  • adjacency_list<>でグラフを構成する型を作る
  • そのインスタンスを作って、vertexやedgeを突っ込んでいく
  • アルゴリズムを実行
  • 結果を得る

という流れのようだ。

そして、vertexやedgeは単純なものであれば元からある型を使えばよいし、プロパティとして複数の情報を持たせたければ構造体などを指定すればよい。
プロパティを自前で用意する場合は、重みをweight_map()で指定する。
距離の結果を得たい場合はdistance_map()を、経路の結果を得たい場合はpredecessor_map()を指定する。

私が使う範囲では、このくらいわかっておけばよさそうだ。

2017/09/01

[c++]Boostのdijkstra_shortest_paths() - 3

第3回。前回はこちら


前回は、グラフの有向や無向の設定だけを見た。
それ以外にグラフの設定で使いそうなのが、プロパティだろう。
経路探索する場合は、vertexとvertexのつながりだけでなく、経路の取捨選択に用いる情報を付加することが多いからだ。
よくあるのは、距離とか、そこを通るのにかかる費用とか。

距離のような単純な情報であればboostが用意していて、edgeのプロパティとして

boost::property<boost::edge_weight_t, int>

などと書いてあげればよい(これはint型の重み)。


ただ、重みの情報は1つだけど、そのルートを通るようになった場合に参照したくなる情報もある。
さっきの例でいえば、重みとしては距離を使うけれども、経路が分かった後には通行料を知りたい、などという場合だ。
そういうときは、自分でプロパティを設定できるようである。


https://boostjp.github.io/tips/graph.html#bundle-property
ここでは、structを作ってプロパティにしている。
何でもいいのかな?
まあ、C++のtemplateはマクロみたいなものだったと思うので、ちょっと種類が異なるグラフ型を作ると、それに関連する関数も新たに作ることになってしまうのだと思うが。

試して分かったが、このプロパティにする型だが、関数内に書いてはダメだった。
グローバルスコープじゃないと展開できないのだろう(私はC++にあまり詳しくないので、推測だ)。


あとは真似をしておけばdijkstraで経路探索したり、距離を表示させたりすることはできた。
しかし、サンプルではせっかくedgeにもプロパティを付けてTokyoやNagoyaを設定しているのに、表示するときには固定文字列を使っている。
かといって、map[v1].nameなどと指定するだけでは芸が無い気もする。

それに、これは2点間だからよいが、複数のvertexがあって経路探索した場合は、どの経路を通ったかをもらって、そこからプロパティを取得していきたいではないか。


https://boostjp.github.io/tips/graph.html#dijkstra-shortest-paths
経路探索して、その経路を出力するサンプルがこちらだ。
プロパティはedgeだけで、int型になっている。
そして経路出力しているところを見ると、parentという変数を使っている。
使われ方は・・・ああ、プロパティサンプルのdistanceと同じ立ち位置なのか。

ただ、プロパティのサンプルではboost::weight_map()を使っているが、ここではboost::predecessor_map()を使っている。
dijkstra_shortest_paths - boostjp
weight_map()はINで、predecessor_map()はOUTだ。
INなのに、なぜ・・・。

あ、dijkstra_shortest_paths()が長いので気がつかなかったが、引数は3つしかないんだ。
そして、第3引数はxxx_map()がドットでつながっている。


Boost Graph Library: Dijkstra's Shortest Paths - 1.65.0

引数が3つのタイプは、これだ。

// named parameter version
template <
         typename Graph,
         typename P,
         typename T,
         typename R>
void dijkstra_shortest_paths(
         Graph& g,
         typename graph_traits<Graph>::vertex_descriptor s,
         const bgl_named_params<P, T, R>& params
);

最後のparamsが、xxx_map()が連鎖しているところになる。
引数が多いタイプも合って、そっちはnon-named parameter versionと呼ばれている。
あまり読んでないが、ここに書いてあるxxx_map()をどんどんつないでいって、指定したいものだけ指定すれば応じた結果が得られるということだろう。


プロパティのサンプルは、こう。

weight_map().distance_map()

経路を求めるサンプルは、こう。

predecessor_map().distance_map()

プロパティのサンプルは重みを別のところから取ってくるからweight_map()を使っているのだろうか。
しかし、それならプロパティにHighwayを指定しなくてもなんとかなるんじゃ無かろうか、と思ったが、それはコンパイルエラーになった。
ではweight_map()だけ外したらどうなるかと思ったら、それはdistance_map()がわからんと言われた。
distance_map()は「UTIL/OUT」になっているから、オプション扱いで、何かの後ろに付けるということか。


weightは任意のプロパティから指定したい、経路の情報は欲しい、ということであれば、こんな感じにするとよいのか。

    std::vector::vertex_descriptor> pred(num_vertices(map));
    std::vector distance(boost::num_vertices(map));
    boost::dijkstra_shortest_paths(map, v1,
            boost::weight_map(boost::get(&Highway::distance, map)).
            predecessor_map(&pred[0]).
            distance_map(&distance[0]));


検証は、次回だ。

[c++]Boostのdijkstra_shortest_paths() - 2

意外なことに、2回目です。
前回はこちら


グラフ - boostjp
このサイトを見て、探索はできるようになったのだが、あまりにも理解できなさすぎて、応用がまったくできない。
理論はもうあきらめるとして(いいのか。。。)、主な使い方くらいは覚えよう。


ツリーではなく、グラフだ。
だから、ノードやブランチではなく、vertexやedgeと呼ぶようだ。
まあ、ツリーでもedgeを使ったりするようなので、そこまで依存した言葉遣いではないのだろう。


このグラフ全体をclass adjacency_listが持つようだ。
派生して使うのではなく、templateになっていて、テンプレートパラメータを指定することでグラフ全体の設定になるようだ。

説明はサイトを読んだ方が早いだろう。
主に変更しそうなものは、グラフの有向(一方向、双方向)/無向と、カスタムプロパティかな。
双方向有向が無向と違うのは、重みが方向によって替えられたり、辺によって一方向にすることができる、というところか。
細かいけど、片方向はdirectedS、無向はundirectedSだけど、双方向はbidirectionalSと末尾が違うので注意だ。


こんな感じで、じわじわ読み進めていこう。

主な使い方、と最初に書いたものの、それですらいつ終わるかわからんが、やらねば終わらぬのだ。

2017/08/30

[git]branch名にスラッシュは使えるが、使うなら最初から使うこと

他の人のgitリポジトリを見ていたのだが、ブランチにスラッシュを使っていた。
作業者ごとに掘っていたり、課題ごとに掘っていたりと、なんか見やすい気がする。

やだ、カッコイイ、やってみたい(ミーハー)!


$ git checkout -b test1
$ git checkout -b test1/help
fatal: cannot lock ref 'refs/heads/test1/help': 'refs/heads/test1' exists; cannot create 'refs/heads/test1/help'

話が違うじゃないか・・・。

ネット検索すると、branch名と同じ名前のディレクトリをmkdirするときにエラーが出たので失敗している、ということらしい。
Using the slash character in Git branch name - Stack Overflow

mkdir -pしてないからディレクトリが掘れないのか?と思ったが、そうではない。

$ ls -F .git/refs/heads/
master  test1

ああ、branchで作るのって、ディレクトリじゃなくてファイルなんだ。
てっきり、ディレクトリを作って、その中に管理ファイルを置くものだとばかり思っていたのだ。
mkdirして失敗するのは、既にディレクトリと同じ名前のファイルが存在しているからだ、ということになる。

branchつくって作業をしていたけど、ついでにこっちの作業も並列で進めたくなって、でも元のbranchから派生させるようなものでもないから今のbranchから作りたくて、どこかの時点でマージさせたい、ということがあって、そこでスラッシュを作って派生しているのがわかるようにしようと思っていたのだ。
アンダーバーで区切ればよいのだけど、単語の切れ目で使っているので、それはそれで分かりづらい。


ともかく、gitのbranch名にスラッシュは使えるのだが、使うなら最初からスラッシュを付けて作っておかないと後からはできないよ、という話でした。

2017/08/29

[c++]Boostのdijkstra_shortest_paths()

Cで、dijkstra法による経路探索を行いたかった。
最短の経路探索法なら何でもよいのだが、思いつくのがdijkstra先生の方法しかなかったのだ。

一応、大昔に受けた授業でやった記憶だけは残っている。
動的計画法だのなんだのかんだの。
だから、アルゴリズムの本を読めば記憶が甦ってくるんじゃなかろうかと期待したのだが、うん、ダメだね。


そして最初に書いたように、経路探索を行いたいだけで、別に経路探索するアルゴリズムを自分で実装したいわけではない。
ライブラリでもサンプルソースでも、動けばよかろうなのだ。

よかろうなのだが、なかなか気に入ったソースが見つからない。
よく見るのは、M x Nの2次元配列を作るタイプだ。
しかし、今回は動的に増えていくので、そういう書き方だとやりづらいし、メモリをいっぱい使うことになるので嫌だ。

1ヶ所見つけたのだが、そこはサイトがGPL1.2で、これはこれでよろしくない。
もう少しゆるめのライセンスがよいのだ。


そこで妥協したのが、C++にすることだった。
今作っているCのライブラリさえ使えればよいので、C++でもよいのだ。

C++といえば、やはりBoostよね。


Boost Graph Library: Dijkstra's Shortest Paths - 1.65.0

うーん。。。すごく見づらいぞ。
蛇のアイコンもあるし、pythonと関係あるのか?

もっとわかりやすいサイトがあるはず、と探すと、ありました。
グラフ - boostjp
ありがたいことに日本語だ。


始点Sから終点Zまでの経路探索をするサンプルになっている。
ノード・・・じゃなくてvertexと表現している。頂点か。
そして、頂点と頂点を結ぶ辺をedgeという。
edgeには重みがあり、それはweightだ。

というのはサンプルソースの最初の方を読んでなんとなく分かったが、型とか使い方になるとサンプルソースを読んでも今ひとつ分からない。
いきなりdijkstraのところからやるのではなく、Boostのgraphというものについての考え方や方針を把握した方がよさそうだ。
これも同じページの最初の方に書かれている。


が、しかしこれは・・・複雑だ。
日本語で説明してあって、さらに例まで載っているからわかるものの、そうじゃなかったら使い切れない気がする。

2017/08/24

[btc]confirmation

Bitcoinだけではないと思うが、ブロックチェーンに関することをやっていると「confirmation」というものに出くわすと思う。

自分がBitcoinで取引するためにトランザクションを作ってブロックチェーンに公開する場合、だいたいこういう流れになる。

  1. 自分が送金したい相手に対してのトランザクションデータを作る
  2. トランザクションデータをブロックチェーンに公開するため、どこかのノードに送信する
  3. (トランザクションデータが正しくて、ブロックチェーンのノードに受け入れられたとする)
  4. そのノードが、他のつながっているノードに対してトランザクションデータを転送する
  5. 一定期間が経つと、マイナーがブロックを作り始める
  6. あるマイナーが作ろうとするブロックに、自分が送信したトランザクションデータが取り込まれる
  7. そのマイナーが他のマイナーとの競争に競り勝ち、作ったブロックがブロックチェーンに公開される

大ざっぱに、だ。
まだマイニングしたことがないので、詳細な流れは把握していない。


さて、confirmationというのがこの流れのどこに出てくるかというと、「ブロックに取り込まれたときが1confirmations」だ。
ブロックに取り込まれるまでは、mempoolという貯木場みたいなところにトランザクションが浮かんでいるだけだ。

では、2confirmationsはいつかというと、1confirmationsになったブロックに、次のブロックが連結したときだ。
以降、ブロックが載っていくごとにconfirmationは増えていく。


一般的に、confirmationが6以上であれば大丈夫、といわれている。

大丈夫?何が??

最初に書いておかねばならんが、私はこの辺の数学的な検証については非常に疎い。
つまり、うん、わからんのだ。。。
だいたいどこにでもそう書いてあるから、そうなんだろう、くらいの根拠しかない。
まあ、6というと、6σとかあるから、なんかそれっぽいな、程度しか言えることがない。


ただ、Bitcoinのブロックチェーンには「展性」という脆弱性がある。
トランザクション展性、などと呼ぶらしい。
詳しくないので割愛するが、実際に開発している間に受けると、かなりびっくりする。
自分がトランザクションを作って、トランザクションをブロックチェーンに公開して、それが自分の立てたノードに受け入れられたところまで確認しているのだが、コーヒー飲んでおしゃべりして、そろそろconfirmationが増えたかと思って確認しようとしたら、TXIDが存在しない、ということになるのだ。


ああいうのを受けてしまうと、いろいろ考えますわな。

2017/08/23

[c/c++]設定ファイルを読みたい

プログラムを作っていて、設定ファイルを使いたいことがある。
引数に設定してもよいのだが、個数が多かったり、同じ設定を何度も使うことになったりすると、どうせなら設定ファイルにしてしまいたいのだ。


Linuxには、これといった設定ファイルの書式がなさそうではあるが、だいたいはこんな感じだと思う。

  • 項目=設定値
  • コメント行は#
  • =の前後にスペースがあったり、空行があってもOK


「項目=設定値」だけであれば、こんな感じのことをやっていけば読込むことができる。

char name[32 + 1];
fscanf(fp, "name=%32s\n", name);

(\0は%32sの中に入るんだっけ・・・)

しかし、こんなのをゴリゴリとコーディングしていくのも面倒だ。
それに、これだとスペースや改行を処理することができないので、割り切ってしまえばよいものの、なんか、ねぇ。

また、そういうのを自作したいわけでもない。


ネットで「linux 設定ファイル 編集」なんて検索しても、期待するものが見つからない。。。
ようやく見つけたのが、こちら。

benhoyt/inih: Simple .INI file parser in C, good for embedded systems

iniファイルのパーサーだそうな。
セクションを[]でわけるし、コメントは「;」だけど、コメントはINI_INLINE_COMMENT_PREFIXESで変更できるらしい。
READMEに載っているサンプルで読込んでいるtest.iniは[protocol]と[user]というセクションがあるけれども、がなくても使えるのではなかろうか?


まずは、ライブラリを作る。

$ git clone https://github.com/benhoyt/inih.git
$ cd inih/extra
$ make -f Makefile.static
$ cd ../examples
$ gcc -o tst ini_example.c -L../extra -linih
$ ./tst
Config loaded from 'test.ini': version=6, name=Bob Smith, email=bob@smith.com

うん、シンプルでよいじゃないか!


では、test.iniのコメントを#にして、カテゴリーを削除したファイルではどうなるか・・・。
うーん、エラーにならず、変な値が読み取れてしまった。

サンプルソースを見ると、handler()の中でsectionを比較するようになっていた。
MATCH()マクロからsection比較している部分をなくすと、読み込めるようになった。

よしよし。


最後に、#をコメントにしたMakefileを載せておこう。

https://gist.github.com/hirokuma/a2c4bab70d43db8ddf17b1a673da1b3e

Makefileでgccの文字列マクロを設定するときって、こうやるのね。。。
#もエスケープせんといかんのは、盲点だった。

2017/08/21

[c/c++]中途半端にハンガリアン記法風の名前を使っている

私がC/C++を覚えていた頃は、変数名などの名前付け方法に「ハンガリアン記法」というものがあった。

なくなるものではないので、今もあるとは思うが、面倒なのであまり使われていないと思う。
私も、ちゃんと使ったことはない気がするのだが、型を変数名に反映させるなんてやめてくれー、と思っていた。


しかし、だ。
自分でコーディングするときに、型を変数名に反映させている場合があることに気付いた。

boolとポインタだ。
boolの場合は「bFlag」とか「b_flag」とかだし、ポインタは「pData」とか「p_data」とかだ。

もしかすると、これもハンガリアン記法になるんじゃなかろうか。
いや、そもそもハンガリアン記法ってなんなのだろうか?


ハンガリアン記法 - Wikipedia

ハンガリー出身の人が考案者だからハンガリアンなのか。。。
チャールズ・シモニーさんらしいから、チャールジアンとかシモニアンとかでもよかったんじゃなかろうか。
でも、逆ポーランド記法みたいなこともあるし、それはそれでよいのかもしれん。


そして、論文に書いてあった「type」を、データ型として当てはめてしまったので型を反映させるような読まれ方になってしまったが、考案者としては「変数の意味や使用目的」と意図していたそうな。

まあ・・・「type」をそう読み取ってしまったのは、仕方ないよな。。。
それに、私もWikipediaを読んだだけで、原文を当たったわけではない。
だから、本当にそうなのかはわからんが、それっぽいよな。


こちらが、たぶん原文。
Hungarian Notation
なんだ、Microsoftの人だったのか。

表に例があるし、コードもあるのだが、データ型を名前にしている感じはしないな。


Wikipediaには「アプリケーションハンガリアン」と「システムハンガリアン」の2種類があると書かれているが、これは論文に書いてあったものではなく、Microsoftがハンガリアン記法を決めたときに作ったものなのかな。


Wikipediaに書いてあるシステムハンガリアン風の書き方で私が使っているのは、これらだ。

  • 論理型(頭にbをつける)
  • ポインタ型(頭にpをつける)
  • ファイルスコープの変数(頭にmをつける)
  • グローバルスコープの変数(頭にgをつける)
  • typedefした型(お尻に_tをつける)

最近はC++を使ってないので、classを作ったらどうするかはよくわからん。
大文字で始める、くらいのルールにしそうな気がする。

ファイルスコープのポインタ型、みたいな合わせ技もあるのだが、それは「mpData」みたいな書き方にしている。

引数は大文字で始まり、スタック変数は大文字を使わない、というルールにしているつもりなのだが、あんまり守ってない。。。
Dataとdataとか、pDataとp_dataとか。
なるべく守ろうとするのだが、1つの関数を書いていて大きくなりすぎてしまったからstatic関数に分ける、なんてことをやってしまうと、変数として小文字を使っているので、関数の仮引数を大文字にしてしまうと面倒になるので放置、ということがしばしば。


ああ、そういうのが変なるールを作ったことによるコストなのだよな。。。

プロジェクトだと、ある程度コーディング規約を決めないとバラバラになりすぎるのだけど、ぎちぎちにしてしまうとコーディング自体が楽しくなくなるので、難しいところだ。

2017/08/18

[linux][c/c++]現在時刻の取得

Linuxで時間の取得を行いたい場合がある。
今の時間だ。
time(NULL)でepoch timeを取得していたのだが、それでよいのか自信がなくなってきた。


マイコンの場合、RTCに設定した時刻が取ってこれるだけで、それ以上でもそれ以下でもない。
それに、RTCから自分で値を引っ張り出さないといけないので、epochも何も気にしようがない。

しかし、time()はきっとライブラリ側でOSが管理しているしくみに置き換えられているはず。
Linuxで時間といえばgettimeofday()だよなあ、と検索したのだが、どうもgettimeofday()は廃止予定らしい。
gethostbyname()もそんな感じだったな。。

推奨されているのは、clock_gettime()
まずは動かしてみよう。

https://gist.github.com/hirokuma/17bdf87bf3c8c6f29008e74635f9984e

2017/08/18 10:10くらいにBash on Ubuntu on Windowsで実行させると、こうなった。

$ ./tst
tv_sec=1503018649, tv_nsec=105938100

ネットでepochを現在時刻に変換するサイトを見つけてやってみると、JSTとして変換すると現在時刻になった。
dateコマンドでは、こうなる(あれこれしているうちに5分くらい経ってしまったが)。

$ date
Fri Aug 18 10:15:53 DST 2017


これは、内部ではUTCで管理していて、出力時にJSTの下駄を履かせているという考え方でよいのだろうか?
(DSTになっているのも気になるが。。。)
VirtualBoxで動かしているXubuntu16.04でも同じになったので、Bash on Ubuntuがそうしているわけではなさそうだ。


そして、epoch timeは各地の時刻ではなく、UTCで出すというのが共通の認識ということでよいのだろうか。
数字しかないので、UTCがデフォルト、のようなルールがないと困るのだけど、明示的に書いてある資料が見つからない。


オライリーの「C言語クイックリファレンス」には、

  • time()は現在のカレンダー時刻を返す
  • これは、紀元と呼ばれる
  • Unixの紀元はUTCの1970年1月1日 00:00:00

とある。
そして、「紀元」は"epoch"だから、epoch timeはUTCということでいいんじゃないかな。
うんうん、そうしておこう。

tig

ファイル履歴管理にgitを使っているのだが、未だにコマンド慣れしていない。
慣れない操作で失敗するのも嫌なのでGUIのツールを使っていたのだけど、最近はクラウド上につくったVMを扱わんといかんことも多くなり、なるべくgitをコマンドラインで使うようにしている。


でも、ある程度はGUIっぽく表示してくれた方が見やすいじゃないか。
そう思って探していると、tigというコマンドが見つかった。

gitを逆に並べたtigだが、コマンドラインで動かすツールながらも、GUIっぽく出してくれる。
なんというか、FDみたいなコマンドになるのかもしれん。
・・・FDってWindowsのみだったかも。


tigの操作は、ちょっとviっぽい。
カーソルの移動がそうだからか。


使うのは、ステージに挙げたりcommitしたりするところが主だ。
git addするとき、ファイルのパスをいちいちコマンドで書くのが面倒なのだよ。

tigを立ち上げて、sを押して更新したファイルの一覧を出し、uを押してcommitしたいものをステージに上げる。
上げ終わったら、大文字のCを押してcommitするエディタを起動する。
うちではnanoが立ち上がった。

historyなんかも重たくなく見られるので、使いこなせると便利そうだ。


ただ、最近はtigする気力も無いので、VirtualBoxでGUIが動く状況であればVisual Studio Codeを使っている。
差分なんか見やすいしね。

2017/08/17

[勉]MIPI

Xilinxからメールが来た。

MIPI D-PHY 搭載のザイリンクス UltraScale+ デバイス

MIPI?
初めて聞く単語なので、これは調べねばなるまい。


Mobile Industry Processor Interfaceの略らしい。

デバイス古今東西(17) ―― 撮像デバイスの変遷と次世代標準インターフェースMIPI規格|Tech Village (テックビレッジ) / CQ出版株式会社

「モバイル機器向け」なのだそうだ。
記事が2010年なので、7年前にはすでにあった規格ということになるな(2003年らしい)。

シリアル通信というと、UART, I2C, SPI, USBなどなど、たくさんある。
そこに連なるようなものなのか、


こちらが、mipi allianceのページ。
https://www.mipi.org/

仕様書をちょっとくらい見てみようかと思ったけど・・・数が多くて止めた。
Specifications Overview

カテゴリーだけで、これだけある。

  • Audio
  • Camera and Imaging
  • Chip-to-Chip/IPC
  • Control and Data
  • Debug and Trace
  • Display and Touch
  • Physical Layers
  • Software Integration

まあ、NFC Forumの規格もたくさんあったし、そういうものかもしれん。


これで終わってしまうのはさすがに悔しいので、Xilinxのメールで紹介された規格くらい調べておこう。

「MIPI D-PHYを搭載」

mipi allianceの説明ページは、こちら
PHYなので、物理層なのだろう。
スマートフォンのカメラやディスプレイ向きのようだ。

技術的な内容は出てこなかった。


MIPI ‐ 通信用語の基礎知識

同期式とのこと。
ソース同期と書いてあるので、クロック線は持たず、データ自体がクロックと同じ意味を持つということか。
マンチェスターみたいな感じかな?
マンチェスターだと1bitを2データで表すが、差動だと1データ分の時間で2データを表現できるので、倍の速度になるのかも。
上限が1Gbpsとなっているので、なにか技術的に上限が発生するのだろうが・・・そこまではわからんな。


これで終わろうと思ったが、最後に見たページではもう少し情報が載っていた。
前田真一の最新実装技術あれこれ塾:第47回 内部ディスプレイ接続規格 (4/4) - MONOist(モノイスト)

高速モードは1.5Gbpsみたいだ。
そして、予想と違ってクロック線があり、ビデオ信号だとレーンを複数用意するようだ。
下手に予想するもんじゃないな。

2017/08/11

hexdumpで16進数を出力したい

バイナリファイルをソースコードに埋め込みたいことがある。
画像データを配列として使いたい場合などだ。

ファイルから読み込んで%02xなどで出力させるだけなのだが、いちいちコマンドを作るのも面倒だ。
hexdumpというコマンドがあるのでやってみたが、オプションを使えばなんとかいけそうなものの、よくわからん。
だいたい、なんで2バイトごとに出すのがデフォルトなんだ?


と、コマンドに文句を言ってもしょうがないので、オプションを調べよう。

hiro99ma blog: hexdumpのフォーマット

0xを付けた出力をしたい場合は、これでよい。
これは8バイトごとに改行しているので、8/1になっている。

$ hexdump -e '8/1 "0x%02x, " "\n"'  abcdef.bin


pythonで、ひたすらずらずら並べた文字列を作りたいこともある。

$ echo "$(hexdump -e '1/1 "%02x"' abcdef.bin)"

echoはなくてもよいのだけど、改行を付加しないので、コマンドラインで実行すると見づらかったのだ。


で、hexdumpを16進数の1桁ダンプ以外で使うことが無さそうなので、aliasに登録しようとした。

alias hexdump='hexdump -e '\''1/1 "%02x"'\'

いやあ、こんなに難しいとは。。
シングルクオーテーションで全体を囲む中にシングルクオーテーションを入れたい場合は、

  • 一度シングルクオーテーションを閉じる
  • \'を付ける
  • シングルクオーテーションを始める

ということをせんといかんそうだ。

青文字がシングルクオーテーションで囲んだ範囲、赤文字がエスケープしたシングルクオーテーションとなる。

alias hexdump='hexdump -e '\''1/1 "%02x"'\'


aliasをシングルクオーテーションで囲むのは、スペースも含めて入れてほしいという場合だけのはず。
まあ、これで登録しても、aliasコマンドで見ると

alias hexdump='hexdump -e '\''1/1 "%02x"'\'''

なんだけどね。

2017/08/07

[c/c++]lmdbでの検索

たまにはFPGAを離れて、DBのことをやってみるのもよいだろう。
そうだな、lmdbなんてどうだろうか?


最後にlmdbのことをやったときは、付属サンプルのmstest.cを見ていくだけだった。
今回は、KEYから検索したり、VALUEから検索するときのことを考えよう。



今のところ、私のlmdbに対するイメージはこうだ。

image


mdb_env_create()で1つのENVを作り、mdb_env_open()する。
ENVからmdb_txn_begin()でTXNを開始し、同じトランザクション内で処理したいものをmdb_dbi_open()でDBIを開く。
あとは、TXNとDBIのセットでmdb_put()したりmdb_get()したり。
終わってトランザクションを確定させたいなら、mdb_txn_commit()してmdb_dbi_close()。
変更したものを破棄するなり、読込むだけで保存するものが無ければ、mdb_txn_abort()だけ。
mdb_put/get()だけでなく、cursor系のAPIもある。


さて、検索するには、どのAPIを使うのがよいのか。。。

いまのところ、私の認識はこうだ。

  • KEYが指定できる場合は、mdb_get()
  • それ以外は、cursor系APIでDBIの中を全部探す

SQLではないので、自分でやるしかないだろう。
mdb_cmp()で比較するようなことができるのかと思ったが、関係なさそうだ。


自分でやるしかないので、全部KEY-VALUEに突っ込むだけではなく、DBIをうまいこと分散させるのもよいだろう。

2017/08/05

[zybo]PetaLinuxでDigilentのチュートリアルが動かん (15)

前回は、ZYBOのPmod JEをたたくドライバに載っているアドレスからリファレンスマニュアルを調べようとしたけど失敗した、というところまでだった。


ならば、正攻法で調べるしかあるまい。
Pmod JEからたどっていくのだ。

image

7本使っているが、1本見ればよかろう。

image

これはIC19Bなのだが、IC19AがZynqだから、これもZynqのピンなのだろう。
V12は、IO_L4P_TO_34という名称なのか。


これで検索して出てくればよかったのだが、それっぽいものが出てこない。
テクニカルマニュアルj_ug585-Zynq-7000-TRM.pdfの「2.8 PL I/Oピン」に載っているT[3:0]がそれか?

image

T0だから、メモリバイトグループT0に属するメモリバイトグループということか。


同じ表の中に、こういうのもあった。

image

IO_L3N_だから、こっちの可能性もある。

詳細は「パッケージおよびピン配置ガイド(pdf)」を参照とのこと。
別ドキュメントかー。


Zyboに搭載されているのは、ZYNQ XC7Z010-1CLG400C。

image

SIOとPS I/Oに大別されている。
PS I/OはPS側から制御するI/Oだろうから、SIOはPL側から制御するのかと思ったが、SIOは「SelectIOリソース」という意味らしいので、PSかPLかを選択できるのかもしれん。

ネットで検索すると、「7シリーズ FPGA SelectIOリソース ユーザーガイド」というPDFが出てきた。
7シリーズはZynqのPL部だから、PL部なのだろう。
Zynqの概略図でも、PL部に"Multi Standards I/Os"というものがあるし。
https://japan.xilinx.com/content/dam/xilinx/imgs/block-diagrams/zynq-mp-core-dual.png


IO_L4P_T0_34という名前だが、こういう意味になると思われる。

  • IO : ユーザーI/Oピン
  • L : 差動ペア
  • 4 : バンク固有のペア
  • P : 差動ペアの正側
  • T0 : メモリバイトグループT0に属する
  • 34 : バンク番号

さっぱりわかりません。。。


まず、バンクの説明図があった。
PLバンクの図らしい。

image

「すべてのHP I/Oバンクは完全にボンディングされていて、すべてのPSバンクは完全にボンディングされている」らしい。
HPと書いてあるけど、表ではHPが0本、HRが100本だったから、HR I/Oバンクだと思う。

  • HR : Hight Rangeバンクのことで、3.3V対応という意味のようだ
  • HP : Hight Performanceバンクのことで、1.8V対応という意味のようだ

Vivadoでも1.8Vを3.3Vに変更していたが、こういう意味があったのか。


ピン配置はASCIIファイルになっているらしい。
XC7Z010のCLG400はこれ
うん、V12はIO_L4P_T0_34で、メモリバイトグループ0、バンク34だね。
そして、I/Oタイプは「HR」とのこと。
さっきの図でBank 34 HRとなっていたから、そのままなのかな。


あとは、ピン配置の図と、ハンダ付けとかそういう説明があったが、今回はよかろう。
ピンの数は、20x20 = 400本のようだ。


わからなかった用語を検索しておく。

差動って、USBとかで使われている正負が逆転したやつだろうか?
それとも、差動増幅というやつだろうか。
なんとなく、前者っぽい。
https://ja.wikipedia.org/wiki/%E5%B7%AE%E5%8B%95%E4%BF%A1%E5%8F%B7#.E9.AB.98.E5.91.A8.E6.B3.A2IC.E3.81.AB.E3.81.8A.E3.81.91.E3.82.8B.E5.B9.B3.E8.A1.A1.E6.8E.A5.E7.B6.9A


というわけで、アドレスについては書いてなかった。

次はデバイスツリーを見る。
これにはアドレスが書いてあったはずなので、そこからたどれるかもしれん。
というより、アドレスを直接ドライバに書くのではなく、最終的にはデバイスツリーから取ってくるようにせんといかんのか。


0x41200000だが、ZynqではなくARMの方(plnx_arm-system.dts)に出てきた。
そっちか!

		gpio@41200000 {
			#gpio-cells = <0x2>;
			compatible = "xlnx,xps-gpio-1.00.a";
			gpio-controller;
			reg = <0x41200000 0x10000>;
			xlnx,all-inputs = <0x1>;
			xlnx,all-inputs-2 = <0x0>;
			xlnx,all-outputs = <0x0>;
			xlnx,all-outputs-2 = <0x0>;
			xlnx,dout-default = <0x0>;
			xlnx,dout-default-2 = <0x0>;
			xlnx,gpio-width = <0x4>;
			xlnx,gpio2-width = <0x20>;
			xlnx,interrupt-present = <0x0>;
			xlnx,is-dual = <0x0>;
			xlnx,tri-default = <0xffffffff>;
			xlnx,tri-default-2 = <0xffffffff>;
		};

ARMの方ではあるが、xlnxとなっているところが多いから、たぶんXilinxがカスタマイズしたのかな。


Zynqの概略PNGを見ると、PS部とPL部の接点は多くなかった。
そういえば、ZynqにAXI GPIOを追加したな。

image

今回のInterface誌に載っていた手順を振り返ると、こうだった。

  • Vivadoで新規プロジェクトを作る
  • AXI GPIOを追加する(Zyboのテンプレートを使ったので、ボード上のLEDにつながっていた)
  • GPIOのブロックを変更して、4bitを7bitにする
  • XDCファイルを変更して、ボード上のLEDからV12などに変更する

元々はボード上のLEDを制御するGPIOだったのだ。
だから、V12が0x41200000に割り振られているのではなく、AXI GPIOでアクセスする先頭が0x41200000で、AXI GPIOのつなぎ先をV12に変更した、というだけのことか。


いつものマイコンだと、ピンと機能が結びついていて、どの機能を有効にするかを設定する、というやり方だった。
FPGAでは、ある程度はピンの使い道を変更できるということだな。
「今回はUARTを2本使いたいけど、そうするとSPIが使えなくなるから、UARTの代わりに空いているI2CにしてFTDIのチップ載せるか」みたいなことはせず「今回はI2C使わないからUART2本とSPIに割り当てよう」ということができるのだ。


というわけで、Pmod JE --- AXI GPIO、というつながりで考えればよさそうだ。


では、Pmod JEのV12がAXI GPIOにつながっているとしよう。
次は、AXI GPIOがARMのGPIOにつながっていることを確認したい。

AXIバスだから、このルートだろう。

image

AXIバスはARMのAMBAバスにつながっているようだ。
AMBA Interconnect、というらしい。

image

インターコネクトは、Zynqテクニカルマニュアルの5章だ。
PSから書込みたいので、M_AXI_GPxになるのかな?

image

「Zynq-7000 All Programmable SoC Data Sheet」の最後の方にメモリマップがあった。
http://www.xilinx.com/support/documentation/data_sheets/ds190-Zynq-7000-Overview.pdf

image

0x4000_0000がPL AXI slave port #0なので、PSがマスター=M_AXI_GP0という認識と一致した。


「5.6.1章 AXI信号」に表があって、「読み出しアドレス」「書込みアドレス」などあるのだが、アドレスっぽい値が書かれていない。
変換できるのかもしれんが、ちょっと私には無理だな。。。

0x4000_0000 + 0x0120_0000、という計算だと思う。
この0x0120_0000というオフセットの計算方法が知りたいのだ。
デバイスツリーでは、0x4120_0000, 0x4121_0000, 0x4122_0000の3つがあるので、何かあると思うのだが・・・。


ZYNQのPS/PL通信をやってみた(4) GPIOテストコードを書く: なひたふJTAG日記

最初のステップでXPSで生成したAXI_GPIOを操作したいけどアドレスがどこにあるか・・・とかそういうことを調べる必要はありません。それらはxparameters.hをインクルードすることで解決されます。

なんですってー!

PetaLinuxのディレクトリ内をfindした。

$ find ./ -name xparameters.h
./tools/hsm/data/embeddedsw/ThirdParty/sw_services/openamp_v1_1/src/open-amp/obsolete/system/generic/machine/zynqmp_r5/xil_standalone_lib/xparameters.h
./tools/hsm/data/embeddedsw/XilinxProcessorIPLib/drivers/common_v1_00_a/src/xparameters.h

ファイルはあったのだが、4年も経過したからか、該当するマクロ名はなかった。
XPSじゃないしね。


しかし、ネットで検索していると、xparameters.hを使っている人が多い。
そして、XPAR_LED_xxxみたいなものもあるので、これは自動生成する類のものと思われる。
GPIOをソフトウェアから制御する | 特殊電子回路


Vivadoでプロジェクトを立ち上げ、Launch SDKして、Newで"Application Project"を選び、Hello Worldを選んだ。
そうすると、なにやらbspというプロジェクトもできている。
その中を見ていくと大量のincludeファイルがあり、xparameters.hもあった。

image

あー、こうやってアドレスがわかるのね。。。


あまり納得できたわけではないのだが、今回はこれでもいい気がしてきたので、これで話を進めよう。

2017/08/04

[zybo]PetaLinuxでDigilentのチュートリアルが動かん (14)

Zybo用にビルドしたPetaLinux v2017.2で、Digilent社のチュートリアルを動かしたいというシリーズ。

・・・なのだが、手始めにInterface誌2016年4月号に載っていたLEDサンプルを動かしている。
そういえば5月号はどんな内容なのだろう、と読んでみたら、私がLinux上で0~9に光らせるようにした処理をFPGA上でやる内容だった。

そこに行く前に、まず今のドライバがどういう作りになっているのかを確認し、Digilentのチュートリアルを動かして、とにかくこのシリーズを終わらせてしまおう。
とはいえ、まだまだかかりそうだな。。。


ドライバのソースファイルはこちら(Gist)。
original: http://www.cqpub.co.jp/interface/download/2016/4/IF1604Z.zip

ZIPとなってるが、元ファイルがZIP提供だったのでそういうタイトルを付けているだけで、リンク先はGistだから安心して欲しい。

ドライバの基本的な部分は、たぶんどこも同じだろうから省略しよう。
FPGAっぽいところ、今回で言えばGPIOアクセスに関係するところだけ見ていく。


そうなると、見るのはまずopen()から。
何かやっていそうなのは、ioremap()とkmalloc()くらいか。

bitは、minorの下位5bit分。
名前からして、デバイスファイルのMAJOR, MINORのminorだろう。
それが、bit = [16, 23] = [0x10, 0x17]の範囲はエラーなんだと。
確かに、mknodしたときは24にしていた。

minorのb4をmodeに割り当てていて、0だったらREAD、1だったらWRITEにしている。
24=0x18だから、WRITEだ。

cookieに使うgpio_table[bit >> 3]は、0x18(0) --> 0x0c(1) --> 0x06(2) --> 0x03(3)、となる。
gpio_table[3]は、

MAP_BASE_ADDR + LED_PIO_BASE + LED_PIO_DATA_OFFSET
  = 0x41200000 + 0x10000 + 0x0

だ。

アドレスが出てきたので、Zynqのリファレンスマニュアルを見ていこう。

image

左側のPLは「CPUおよびACP」、右側のPLは「その他のバスマスター」。

ここからたどっていけばわかるだろうと思ったのだが・・・さっぱりわからん!
GPIOのピンとアドレスがマッピングされているだけではないのか?

Zynqだからなのか、Cortex-Aだからか、いきなりリファレンスマニュアルを読むのは早すぎたようだ。。。

2017/08/02

[xfce]thunarでのパスコピー

Linuxの環境として、Xubuntu 16.04を使っている。
AndroidのビルドがUbuntuで説明されていたのでUbuntuを使いだし、でもUnityになって使い慣れず探していたら、見つかったのがXubuntuだった、という流れだ。
Unityは、メニューが画面上部固定なので、いちいちマウスカーソルを動かすのが面倒でね・・・。
廃止になるらしいから、次は試してみるかも。


Xubuntuは、ウィンドウシステムとしてXfceというのを使っている。
読めないけど、ネズミの絵が出てきたり、テキストエディタがMousepadだったりするので、似た発音なのかもしれない。
XfceのAboutを見ると「collection of programs」となっているので、ウィンドウシステム(xfwm4)を含んだ一式らしい。

さて、よく使うことになるファイルマネージャーだが、デフォルトではthunarというものになっている。

image

これの、パスをコピーする方法が分かっていなかったのだ。
ファイルを右クリックしてプロパティを表示させ、そこに載っているパスをコピーしていたのだけど、さすがにめんどくさいし、方法があるはずだ、ということで検索した。


[SOLVED] Thunar: what is hot key to display path (e.g. for copy)
Ctrl+Lで移動用ダイアログを表示させると現在のパスが出ているから、それでいんじゃないの、ということのようだ。
まあ、これはこれでよいか。


しかし、ファイル名を含んだパスだと、このあとでファイル名だけコピーせんといかんから面倒だな。。。
と、何気なくファイルコピーの要領で、ファイルを選択してCtrl+CしてMousepadにCtrl+Vすると、フルパスが入っているではないか!
空のディレクトリだと使えない技なのだが、それだったら1つ上に上がって選択すればよいか。

あとは、メニュー「View > Location Selector」で"Toolbar Style"にしてもよいかも。
これだと、パンくずリストではなく、昔のExplorerのようにテキストでコピーできる。
昔はレジストリの編集をしてまでもテキストボックスにしていたのだが、最近は「パンくずリストもありやん」と思うようになった。
まあ、あやつはクリックすると切り替わってくれるからな。


最近はXilinxのPetaLinuxを扱うこともあって、Linuxもよく使っているから、もうちょっと使い慣れないともったいない。
歳を取ると、使い慣れる時間がもったいない気もするのだが、まあ気長にやるさ。