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もよく使っているから、もうちょっと使い慣れないともったいない。
歳を取ると、使い慣れる時間がもったいない気もするのだが、まあ気長にやるさ。