2017/01/31

総務省指定の番号は検索できないのか?

今年になって、PN7150の評価キットプレゼントに当選した。
規格は、こちらだ。
https://twitter.com/nxpfan/status/802067660779327488

弱いけど、一応無線を出すのだが、展示されていた写真(こちらはArduino用)には、総務省指定のシールが貼られていた。
「第AC-16082号」と書かれている。
https://twitter.com/nxpfan/status/802070209028702208

貼ってあるのは、Arduinoへの変換ボードでは無くてPN7150の載ったボードの方だし、FCC IDも一致しているので、うちのRaspberry Pi用でも同じ番号になると思っていて良いのだろうか?

ちなみに、こちらがうちの子だ。

image

技適の番号と違って、総務省指定の番号を検索する方法が分からないのよね。。。
PaSoRiなんかも総務省指定のシールが貼られているけど、探せていないのだ。
twitterで@nxp_fanさんにリプライで質問してみたけど、そういう場所でするような質問でも無かったかな。
まあ、製品にするわけでも無いし、周囲に無線が飛び散っているわけでも無いので、あの写真をもって指定されているということにする。

2017/01/31 23:05更新

返信いただきました!
うちの子も、この総務省指定の番号でよいそうです。
https://twitter.com/nxpfan/status/826424981324079105

 

しかし、@nxp_fanさんの写真に出ているArduinoは、うちにあるやつと見栄えが違うな。
LEDも載ってるし、小さいボタンはリセットか?
Raspberry PiでもBBBでもなさそうだからArduinoだと思っているのだけど、こういうのもあるんですな。

クラウドは近い方がよい

小ネタです。

今年から、お仕事用にAzureを使い始めました。
便利よねー。
Azureだけじゃないと思うけど、「鉄人、Ubuntu 16.04だ!」とリモコンを操作するだけで、Ubuntu 16.04が使えるようになるのですよ(若い人は『鉄人28号』を調べてみよう)。

 

Pythonで作ったアプリで、MQTTを使って、Azureで立てたUbuntu VM間で通信していたのだけど、何だか遅い。
まあ、Pythonってスクリプト言語だし、しょうが無いよねぇ、と、放置していた。
TeraTermでコンソールを入力するのももたつくけど、クラウドってそういうもんなんだろう。

とは思ったものの、速くする方法がるのかもしれないと思い検索していると「リージョンを日本にする」というのが見つかった。
リージョン? 領域ってこと?
そういえば、VMを作るときに、米国とか何とかがデフォルトだったので、そのままにしていたが、あれのことだろうか?

BizSparkという、多少制限があるものの無料枠が毎月更新されるスタートアップ企業向けのサブスクリプションで、日本に一番近いのは「東南アジア」だった。
リージョンの変更、ということはできないらしいので、新しくVMを「東南アジア」で作って、まだ大したファイルを置いていなかったのでscpでコピーした。

は、速いじゃないか・・・・・・・・。
TeraTermの文字入力も、ローカルでコンソールをたたくときに比べれば少しラグがあるように感じるものの、ストレスなど感じるような速度ではない。
あの、入力しても文字がすぐに表示されなかったのを我慢していたのは、なんだったんだ。。。
Pythonでの通信速度も、トータルで秒単位の短縮ができたし。。。

 

いや、米国を選んでいたのは気付いていたのだけど、「西日本」は選べなかったので、米国でもそげん変わらんやろう、と思っていたのだよ。
ちなみに、無料試用版は1ヶ月までしかVMなんかは使えないようだけど、これは「西日本」も選択できる。
使わないまま終わってしまいそうなので、慌てて作ってみたが、もうローカルでコンソールをたたいているのと変わらんくらいの速度だ。
"F1S"という、そこそこよいサイズのものを選んでいるというのもあるだろうが、いやはや。

2017/01/29

[android][nfc]Beamアプリを作る

HCE, Reader modeと来たら、P2Pをやらねばならぬのぅ。
というわけで、Android Beamの、NDEFを投げたり取ったりするだけのアプリを作る。
大きいファイルのやりとりをするサンプルもあるが、今回はNDEFだけだ。
Sharing Files with NFC | Android Developers


Androidで使えるO2O技術まとめ解説(終):AndroidビームとPush通知で最強のO2Oアプリを作る (3/3) - @IT
ここら辺にサンプルがあるので、見れば分かるだろう。
あと、NFC Hacksも読みながらやっている。

createNdefMessage()が呼ばれるタイミングは、端末を向かい合わせて、星が流れる画面になったところだ。
LLCPのデータ交換が行われるようになったところ、といえば良いだろうか。
この状態で小さく表示されているアプリをタップすると、相手にデータが送られる。
タップというよりは、相手の方に押すというイメージだろうか。
そして、相手にPUSHされるとonNdefPushComplete()が呼ばれる。

 

まずは、ここまでをコミットしておく。
EditTextに文字を入れ、別のAndroid端末と向かい合わせ、星が流れる画面になったらサムネイル画面をタップする。
そうすると、相手に送られるであろう。
https://github.com/hirokuma/AndroidBeamSample/tree/ca064f1c87acfd396e4ca6eef4832ef847911087

ButtonやTextViewは使っていないので、気にしないでおくれ。


受信する方は、NDEFタグの読み取りと同じだそうだ。

今回はNDEF Textを送受信している。
Textのところは、こちらからお借りした。
なっぴーさんもともきーさんも、お二人とも元気だろうか。。。
ReadRTDText/HomeActivity.java at master · bs-nfc/ReadRTDText

 

Textの送受信まで取り付けたのが、こちら。
https://github.com/hirokuma/AndroidBeamSample/tree/69b3c0eca2016386cb30a5d1a86a987c4d245281

NDEFなんだけど、IntentではactionがTECH_DISCOVEREDでやってくるのよねぇ。

NDEF Textで文字列を送ったが、バイナリデータを送りたい場合はcreateExternal()がよいのだろうか?
気になるところだが、今回はおしまい。

[android][nfc]Reader modeアプリを作る (2)

私も、AndroidのNFC reader modeサンプルを作った。
hirokuma/AndroidReaderSample

まねしたつもりはないのだが、前回参考にしたサイトと同じような内容になってしまった。
androhi/NFCReaderModeSample: NdefAdapter.ReaderCallbackのサンプル

まあ、API呼んで、コールバックされるだけなので、IDを取得するだけであれば、そんなに差が出ないだろう。

 

Nexus5で動かしているのだが、普通のタグ(HCEじゃないやつ)は読めるのだが、Android BeamしているNexus7をかざすとNFC機能自体がおかしくなるのか、普通のタグも読めなくなってしまう。
時間が経てばよくなるわけでも無く、一度Reader modeをdisable-->enableさせないと動かないようだった。
うーん・・・・・・・。

 

ただ、AndroidのCardReaderサンプルは、そういうことが起きていないような気がする。
私のアプリだと、AndroidのCardEmulationサンプルにかざすとNFCタグが読めなくなるのだが、CardReaderサンプルでは何かしているのだ。

面倒だが、サンプルが何をしているか調べるか。


まずは、CardEmulationから。

AndroidManifest.xmlの<service>で、HOST_APDU_SErVICEやxmlでAIDリストの指定をしている。
Activityでは、AccountUpdateというクラスが文字入力の監視と、変更時にHCEが返す値の更新なんかをやっているのだろう。

CardServiceがHCE動作をしている。
processCommandApdu()が入り口になっていて、SELECT FILEで自分のAIDが指定されていれば処理して、そうでなければ処理しない、というだけのようだ。

 

では、CardReaderを見ていく。

AndroidManifest.xmlで<intent-filter>が設定されている。
Filtering for NFC Intents」によると、NFCタグをかざされたときに自アプリを起動される対象として選んでほしいときにつけるようだ。
優先度を読み解く図があったように思うが、今回は関係ないのでよかろう。

ActivityでReader modeを有効にしているのは、ここ
対象はNFC-Aで、NDEFチェックをしないようにしている。
処理本体は、LoyaltyCardReader

 

うーん?
私のReader modeサンプルがAndroid Beamを受けると動かなくなるというほどの違いはなさそうだが。。。


あ、CardReaderサンプルでenableReaderMode()に与えるフラグにNfcAdapter.FLAG_READER_NFC_Fを追加したら同じ動作になった!
これって、何らかのバグじゃなかろうか。。。

HCEしている方には、こういうログが出た。

E/BrcmNfcNfa: llcp_link_activate (): Failed to parse general bytes

そのあとで「--------- beginning of system」と出ている。
Reader側はかざしたときのログは出ないが「beginning of system」のログは出ている。
確か、このログはserviceが起動しているときに出るような気がするので、もしかしたらNfcServiceなどが再起動しているのかもしれない。

FLAG_READER_NFC_Fを追加しても、ちゃんとNFC-Fのタグは読めるのだ。
単に、LLCPを受けるとうまくいかない、というだけである。
そういえば、AndroidのLLCPはNFC-Fでやっていたような気がするので、そこら辺が影響しているのかも。

 

うちにはNexus5と7しか端末がないが、どちらもBroadcomのチップだったように思う。
だから、Android側なのかドライバ側なのかは切り分けができんな。

とりあえずの回避策は、HCEのタグを読みたくてenableReaderMode()を使うのであれば、相手がNFC-Fになることは(Android6までは)ないので、FLAG_READER_NFC_Fは付けないようにする、だろう。

Android7ではHCE-Fがあるらしいから、さすがに直っているのかもしれんが、じゃあReader modeになる方もAndroid 7じゃないといけないのか?という疑問が出てくる。
が、うちにはAndroid7が使える端末がないので、確認できんな。

ひとまず、githubに置いておくサンプルからは、NFC-Fを外しておこう。
https://github.com/hirokuma/AndroidReaderSample

2017/01/28

[android][nfc]Reader modeアプリを作る (1)

HCEは動いているようだが、Reader Modeになるアプリを作ったことがないことに気付いた。
ならば、やらねばならぬのぅ。

 

Android 4.4で追加されたNFC reader mode - Qiita
「盛り上がっているのか盛り上がっていないのか」で始まるこの記事は、だいたい3年前のようだ。
当時からそうだったのだけど、未だによくわからないですな。。。
私も、バスや電車に乗るときはnimocaを使っているけど、買い物をするときは現金だし。

ただ、技術者にできる特権として、技術を提供できる、というものがある。
それが、たとえマイナーだったとしても。。。
まあ、私はNFCという技術がけっこう気に入っているので、なるべく使っているというしだいだ。

 

さて、脱線はここまでにして、Reader modeを見ていこう。
ActivityがReader modeになって、Android Beamなどに対応しなくなるという動作らしい。


このBeamを止める動作は、HCE側が同じことできないだろうか。。。
HCEしても、Windowsにかざすと、こちらはP2Pされたと思ってSNEPしてしまうのだ。
Reader modeとHCEが両立できるなら、Windowsでもタグとして認識してくれそうな気がする。
設定画面でAndroid Beamを止める設定はあるのだが、これは下回りとしては止まっていなさそうなのだ。
SNEPはしないものの、LLCPの何もしないやりとり(BLEでいえば、Empty PDUだけのやりとり)はしていそうな気配がある。

 

こういうときは、PN7150だ!
AndroidのCardReaderサンプルを起動させて、nfcDemoApp pollしたPN7150にかざすと、Android Beam(LLCP)を検知していない。
しかし、同じくAndroidのCardEmulationサンプルを起動させてかざすと、LLCPしているログが出続けている。

設定画面でAndroid Beamを無効にしてもLLCPしているログは出た。
NFC自体を無効にすると、出なくなる。
しかし、そこからNFCを有効にすると、私のHCE Sampleタグが読めた。
Android Beamを有効にしても、まだ読めている。
そして、何かをトリガにしてAndroid Beamが有効になるようなのだが、トリガが何かは分からなかった。
けっこう放置したけどHCEタグしか読めず、Google Mapアプリを立ち上げたらLLCPログが出始めた。
ポイントは、NFCを無効にする前にAndroid Beamだけを無効→NFC無効→NFC有効→Android Beam有効、の順番だ。
Android Beamだけを有効にしてもLLCPは始まらず、NFC有効時にBeamが有効なら同時に動かすし、SNEPするアプリが起動すればそれはそれで動かす、という動作か。
まあ、ホーム画面をBeamしてもうれしくはないしな。

私が作ったHCESampleサービスも入っているのだが、これはロック画面以外では読み取れなかった。
これは、作り方がよろしくないだけかもしれないので、また考えるとしよう。


軽くLLCP/SNEP/Android Beamの動作を書いておこう。

NFCは、R/WであるInitiatorがTagであるTargetにリクエストを送り、Targetがレスポンスを返す、という通信になっている。
TargetがInitiatorに対して自発的に送信することができないのだ。
しかし、P2Pのようなデータ交換ではどちらがデータを送りたくなるか分からないので、通信している間は常にInitiatorがTargetに何かを送信し、TargetがInitiatorに何かを返信する、ということをやっている。

InitiatorがR/Wとして動作するのか、P2Pの親として動作するのかは、ISO/IEC 18092に書いてあったと思う。
Targetを捕捉してすぐにその判断が行われ、動作分岐するのだ。
RC-S620/SのリファレンスマニュアルではP2Pになるときの動作が書かれているのだが、違う分岐に行くとHCEすることができるだろう。

SNEPは、LLCPでNDEFのタグを投げる、Simple NDEF Exchange Protocolのことだ、。
Android BeamはSNEPでアプリの情報(AAR)を送信していたはず(昔は、Android Pushというプロトコルもあった)。

 

だから、P2Pとして動作せずにR/Wとして動きたいときは、どちらかがLLCPしないようにすればよいのだけど、HCEはバックグラウンドで動くから、いつLLCPをやめる/戻すのタイミングがわからないということで、R/W側がやらざるを得なくなったというところか。
だって、他のアプリがAndroid Beamするつもりで動いているのに、裏で動いているHCEのせいで動作しなかったら「なんで??」ってなるよねぇ。

じゃあ、HCEがサービスじゃなくてアプリの一部として動作するのであればBeamはしなくていいやん、と思ったのだが、このAndroidサンプルはタグを読んでReaderアプリが起動していなかったら起動させる、ということをやっているようなのだ。
ただ、Google Playアプリが起動するだけなのでよくわからないのだが。。。
HCEするアプリの方に数字を打ち込むようになっているから、それがGoogle Playのアプリに関連づけられているのかもしれん。

すまん、サンプルがどういう動きをするのかは読んでいないのだ。。。
しかし、相手のアプリを起動させるためにBeamをしているだけであれば、HCE側もなんとかできるかもしれない。
希望だけ持っておこう。


サンプルを作ろうと思ったが、Qiitaの記事を書かれた人のサンプルがシンプルなので、それを見るのがよいだろう。
とはいえ、私も自分で実装しておかねば、今後使うときに困るので、自分なりに作っておこう。

 

機能として必要なのは、NfcAdapter.enableReaderMode()と、その引数で指定するNfcAdapter.ReaderCallbackクラスの派生クラスのインスタンスだ。
NfcAdapter.ReaderCallbackには、onTagDiscovered()だけがあればよさそうだ。

こちらのサンプルも、AndroidのサンプルもenableReaderMode()の最後の引数がnullだった。
何かと思ったら、reader modeの追加設定などができるみたい。
なんだろう、onTagDiscovered()が呼ばれたときに渡すデータを設定できるのかな?

また、APIの説明文に「disabling any peer-to-peer and card-emulation modes」と書いてあるので、HCEしているときにBeamを止める、というのは、少なくともこれではできないということになる。。。
この辺りは、やはりどうしようもないな。
やりたいなら、利害関係が発生しないように専用端末を作るしかないだろうか。
HCEする自アプリが起動していたせいで、他のアプリがSNEPする機会を失った、などと訴えられても困るものだ。

[android]レイアウト再び

Androidアプリを作っていて、格好がよいのは求めていないのだが、とにかく文字の入力をさせたいとか、文字列を表示させたいとか、そういう気持ちがある。
が、たったそれだけのことをしたいだけでもレイアウトをちゃんと作らないと、そもそも表示されてくれない。。。

何度やっても覚えないレイアウトの作り方なので、今回は趣向を変えて、以下に絞りたいと思う。

  • EditTextが1つと、それを確定するボタン1つ
  • 履歴用のTextViewが2つで、文字を追記していくことで履歴を残していく。スクロールで過去のものも見える。
  • 1画面に収める

image

TextViewもスクロールできたような気がするけど、ScrollViewの中に入れ込むサンプルを以前作ったことがあるから、今回もそうする。


縦に3段、1段目は横に2列。
だから、全体はLinearLayoutのvertical、1段目はLinearLayoutのhorizontal、2段目と3段目はScrollViewにすればよいだろう。

image

image

1段目が全領域を占有してしまった。。。
たぶん、どれもlayout_heightのデフォルトがmatch_parentだからだろう。
これをwrap_contentにすれば。。。

image

1段目は中身があるから高さができるけど、2段目と3段目は中身(content)が空なので、それにwrapすると高さが0になってしまうのだろう。

2段目と3段目の、デフォルトでLinearLayoutが入っていたものを、TextViewに変更する。
先にLinearLayoutを削除してからTextViewを追加しないと、「ScrollViewは子供が1人しか入れられません」と怒られる。

image

image

うーん、ましになったが、期待したものではないな。
1段目の高さはwrap_contentのままでよいのだけど、2段目と3段目は残りの領域を半分ずつ使ってほしいのだ。

そういうときは、1段目はそのまま、2段目と3段目のlayout_heightをmatch_parentにしたままlayout_weightに0以外の同じ数字を入れてみた。

image

layout_weightは、0.5でも1でも100でも、単に比率を見ているようだ。
ただ、数値の比率がそのまま自分の比率になるのではなく、相手の比率になる・・・?
以下は、2段目を1、3段目を2とした場合だ。

image

https://developer.android.com/training/basics/firstapp/building-ui.html#Weight

weight 値は、兄弟ビューが使うスペースと比較して、それぞれのビューが使う必要がある残りのスペースの分量を指定する数値です。

納得いかん。
URL先の例では、レイアウトの方向が水平で、Buttonはwrap_content、残りをEditTextが使い切りたい、というパターンだ。
だから、EditTextはlayout_width="0dp"で、layout_weight="1"になっている。0以外だったらなんでもよいのだろう。

うちの例は、事情が違う。
まず、contentに影響しないので、match_parentになる。
お互いがmatch_parentだったら分割してくれないか、と思ったが、おそらく上から順に評価されるので、2段目がmatch_parentで全部使ってしまい、3段目は高さがなくなってしまう。

 

と思ったが、layout_heightというか、layout_weightが計算される方向は0dpにしておくみたいだ。
https://developer.android.com/training/basics/firstapp/building-ui.html#Weight

2段目と3段目のlayout_heightを0dpにすると、layout_weight通りの比率になった。

image

content_wrapは残った余白をベースに計算するけど、match_parentは全部占めたところから計算するから方向がマイナスになるというか、比率が逆になるというか、そういうことになったのだろうか。

 

よし、実機(Nexus5)に焼いてみよう。

image

比率は合っているのだけど、キーボードが出てきて、そのまま圧縮されてしまった・・・。
こういうのが良い場合もあるかもしれないが、今回は上に載っていてほしい。

<activity> | Android Developers
AndroidManifest.xmlの<activity>の中にandroid:windowSoftInputModeを"adjustPan"にすると、メインウィンドウのサイズは変更されないとのこと。
layoutのXMLでは解決できないのね。。。

<activity android:name=".MainActivity" android:windowSoftInputMode="adjustPan">

image


Nameの高さが、横のButtonと同じ高さになってほしい気もするが、気にしないことにしよう。
EditViewの背景を、LinearLayoutの背景色と同じにしてしまえば気付かないのだろうけど、私としては「入力はここ!」というのが目に見えてほしいのだ。

LinearLayoutの中にpaddingだかmarginを設定して、中のlayout_heightをmatch_parentにすればいけるような気もする。
いけるのか・・・。
・・・うーん、いけなくもないけど、Buttonはああいう画像を使っているだけなので、見た目の高さと一致しないようだ。

 

というわけで、このままにしておく。
activity_main.xmlを記録として載せておきたいところだが、うちのブログエディタ(Open Live Writer)がプラグインなどにまだうまいこと対応してなくて、ソースが貼れないのだ。
Gistに貼っておこう。
https://gist.github.com/hirokuma/077a821563242c921cda4ae64b5f1fed

[勉]go (1)

しかさんに、Pythonからgoに変換する、というものを教えてもらった。
が、goなんて試して大丈夫だろうか?
Pythonを使ってから、Cに戻っても文字列をシングルクオーテーションで囲もうとしたり、セミコロンを付け忘れたりと、多少困ったことになっているのだ。

が、ソースファイルの一部を見て「あ、これはgoだね」くらいは言えるようになっておきたいというのはある。
Hello World程度はやっておこう。


まず、インストール。
Ubuntu on Windowsで試そうとしたのだが、困ったことに、なぜかgoがインストールされていた。
したっけ。。。最近、別の作業でインストールしたような気がしなくもない。

$ go version
go version go1.6 linux/amd64
$ ls -l /usr/bin/go
/usr/bin/go -> /etc/alternatives/go*

今日の時点では、最新版は「go1.7.5 (released 2017/01/26)」なので、aptでupdateしたり、purgeしてinstallし直したりしたが、そもそもpurgeしてもgoコマンドが使える。
なんなんだ、一体。。。

 

https://golang.org/doc/install#uninstall
goディレクトリを削除、という方法なのか。

$ ls -l /usr/bin/go
/usr/bin/go -> /etc/alternatives/go*
$ ls -l /etc/alternatives/go
/etc/alternatives/go -> /usr/lib/go/bin/go*
$ ls -l /usr/lib/go/bin/go
/usr/lib/go/bin/go*

たらい回しにされたが、/usr/lib/goディレクトリが本体のようだから、それを削除すれば良いことになるのかな。

そして、wgetでtar.gzファイルを取ってきて、tarで展開すると、goディレクトリが出てくる。
これを/usr/localに移動させて、/usr/local/go/binにPATHを通せばよい。

$ go version
go version go1.7.5 linux/amd64

~/.profileに追加するよう書かれているが、.profileを見ると~/.bashrcがあれば読込んでいるので、今回は.bashrcでよいだろう。

そして、/usr/local/go以外に置くのであれば、GOROOTを設定する必要があるらしい。
では、さっきまで/usr/lib/goに入っていたのだが、その場合はGOROOTは/usr/lib/goだったのだろうか。。。
gccなんかは、実行ファイルさえ動けば位置の設定などせずに使えるけど、ああはならなかったのだろうか?
あるいは、なにか便利なことがあるのかもしれない。

 

そしてGOPATHだ。
これを設定しておかないと、なんか、いろいろうまくいかなかった記憶がある。
今回は、~/Prog/golangにしておこう。
Progはシンボリックリンクで、lxssではなく普通の場所にしている。
テキストエディタを使うのは、lxss以下だとやりづらい。


https://golang.org/doc/install#testing

動作確認。
GOPATHを設定して、src/github.com/user/helloにhello.goというファイルを作るらしい。
なんだよ、github.comって。。。
変に反発して、~/Prog/golang/hello/hello.goという構成にしてみた。

$ go install hello
can't load package: package hello: cannot find package "hello" in any of:
        /usr/local/go/src/hello (from $GOROOT)
        /home/xxx/Prog/golang/src/hello (from $GOPATH)

ちっ。
$GOPATH/src以下にないとだめなんだ。
つまり$GOPATHの中には、binとsrcがいるということだ。

あらためて、~/Prog/golang/src/hello/hello.goという構成でやってみる。

$ go install hello
go build hello: /usr/local/go/pkg/tool/linux_amd64/link: read |0: interrupted system call

ん??
これ、前回もなったな。。。
確か、2回同じことをするとビルドできたような。

$ go install hello
$

できた。
・・・これでよいのか?

$ ls $GOPATH/bin
hello*
$ hello
Hello, world!

動いた。

$ file $GOPATH/bin/o
/home/xxx/Prog/golang/bin/hello: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), statically linked, not stripped
$ ls -l$GOPATH/bin/hello
-rwxrwxrwx 1 root root 1642158 Jan 28 11:44 /home/xxx/Prog/golang/bin/hello*

意外と大きいな。

$ strip $GOPATH/bin/hello
$ ls -l $GOPATH/bin/hello
-rwxrwxrwx 1 root root 1028488 Jan 28 11:47 /home/xxx/Prog/golang/bin/hello*

まあ、static linkしているから、こんなもんか。
gccだと共有ライブラリを使うのがデフォルトだから、実行ファイル自体は小さくなるだろう。
Execution Modeというのが関係しそうな、しなさそうな。。。まあ、忘れよう。
Go Execution Modes - Google ドキュメント


動いたものの、気になるのはinterrupted system call。

go build command-line-arguments: read |0: interrupted system call · Issue #349 · Microsoft/BashOnWindows

uowの問題で、Build 15019では直るのだとか。
これがWindows Updateのようなものなのか、Anniversary Updateみたいなものなのかは、よくわからんな。

 

動かないことはないので、次回がいつになるか分からないが、そのときはもう少し見ることにしよう。

2017/01/27

[rpi]Pi1/2のどちらでも動かしたいときはコンパイルオプションに注意

Raspberry Piのgithubでは、クロスコンパイラが4種類置いてある。
どれを使うのがよいかは、むかし調べて、どれでもいいんじゃないの、で終わらせた。
hiro99ma blog: [rpi]クロスコンパイラはどれがよいのだろう

 

しかし、先日、ちょっと考えねばならんことがあった。
「ARM版」ということでバイナリ公開されているツールがあってダウンロードしたのだが、Raspberry Pi2では動くものの、Pi1ではちらりとも動かなかったのだ。

Illegal instruction

結局ソースからビルドし直し、動くものはできた。
このときは「arm-rpi-4.9.3-linux-gnueabihf」を選んだのだが、その理由はちょうどcommitコメントに「with Pi 1 support」と入っていたからだった。

 

Pi1はARM11、Pi2はCortex-A7のようだ。
ARM11はARMv6、A7はARMv7ということで、使える命令はv7の方がちょっと多い。
その部分が「命令不正」ということで、Illegal instructionを引き起こしているのだろう。

 

ARM Cortex-A Processors and GCC Command Lines - Blog - Software Tools - ARM Community

NEONというSIMDのコプロセッサみたいなものが載っていて、その命令が生成されたのか。
SIMDは1命令で複数の並列計算を行うようなイメージだ。
座標の変換に行列計算をしたりするけど、ああいうのを1命令でできるとか、そんな感じだ。
PentiumでいうところもMMXとでも思っておけばよいだろう。

 

こちらもリンクを載せておこう。
KMC Staff Blog:ARMのNEONのSIMD命令をgccのオートベクタライズの最適化で使う方法
-mfpu=neonと付けておけば、最適化オプションでうまいことやってくれたりするようだ。

 

ということは、くだんのバイナリは-mfpu=neonでビルドされていたということだろうか。
だったら、クロスコンパイラは好きなのを選んでよいという結論は変わらんのか。

[uow]mvで固まることが多いが、sourceの末尾スラッシュを除けばよい

"Bash on Ubuntu on Windows"という名称は、もうちょっとなんとかならんだろうか。。。
Bashだし、Ubuntuだし、Windowsなので、間違ってはいないのだけど、並べればよいというものでも無かろう。
頭文字だけ取って"bouow"というのも考えたけど、ちょっと長いし、今ひとつだ。
やるなら、

  • Bash on Windows
  • Ubuntu on Windows

くらいでよいんじゃなかろうか。

今回は、Ubuntu on Windows、を略して、uowで進めてみよう。


mvでディレクトリ移動をすると、uowではなく、mv自体が固まってしまうことが多いようだ。
Ctrl+Cなどでも終わらせられないし、ウィンドウもなかなか閉じない。
ウィンドウが閉じた後、uowを立ち上げても、ウィンドウだけ開いてbashが起動しない。

そして、これはどうやっても消えず、uowのコンソールを終了させても消えず、タスクマネージャでも「Mv」で消せず、再起動しようとしても固まってしまい、電源ボタン長押しで強制終了させるしかなくなってしまうようなのだ。。。

uowは開発目的だし、変なことしない方がよいとは分かっているのだけど、mvなんか無意識にやってしまうよねぇ。

 

https://github.com/Microsoft/BashOnWindows/issues/703

スラッシュが入っていると失敗する?
いま固まってしまっているので、後で試そう。。。

$ ls
RaspiKernel/ arm/
$ mv RaspiKernel arm
$

できた!
いつも、先頭だけ入力してTab補完してもらっていたから末尾に/がついていたのだけど、それを取り除けばよいのか。

おびえつつも、destinationの方にスラッシュを付けてみた。

$ mv RaspiKernel arm/
$

これもOKか。

ということは、source側の末尾にスラッシュがある場合のみ取り除けばよいのか。
スクリプトを書いてスラッシュを取り除くことも考えたが、まあ、移動させたいsourceの末尾にスラッシュがあるのも変な話だから、体で覚えていくようにしましょうかね。

2017/01/26

[py][raspi]なるべくpythonを速く動かしたい

手軽にpythonを高速で動かす方法がないか調べた。
なお、主に速くしたいのは、Raspberry Piでの動作だ。


最初に見つかったのが、PyPy。
PyPy - Welcome to PyPy
かわいいなまえですね。

virtualenvとかいうのを使いそうに書いてあったけど、まだ使ったことが無い。。。
よくわからなかったので、apt-getしたらインストールできたと思う。

ただ、困ったことに、pipコマンドはpythonもpypyも"pip"なのだ。
パスが違いそうだけど、せめて名前は変えてほしかったところだ。
/usr/bin/pipがpythonのpipで、/usr/local/bin/pipはpypyのpipだったんじゃなかろうか。

あ、pypyのpipは、確かこちらを見ながらやったと思う。
pipをPypyから利用できるようにするよ!

「思う」が多くて済まんね。
あれこれやったので、記憶が残っていないのだ。。

 

pythonでpip installしたものも、pypyで動かすならpypyのpipでinstallがいる。
使っているものが標準でよく使われるものだったためか、pip自体はできた。

が、だ。
Raspberry Piを使ったのは拡張ピンヘッダで他の機器を制御するライブラリが既にあったためで、それはCで書いていた。
どうやら、インターフェースだけちょろちょろっと変更して共有ライブラリにすればimportできるらしいので、Python/C APIというやつで呼び出せるように作っていた。
PythonのC言語拡張モジュール作成ガイド — PythonのC言語拡張モジュール作成ガイド
このライブラリがimportできないのだ。

PyPyとしては、拡張モジュールはCFFIというやつでやるのを推奨しているらしい。
Writing extension modules for pypy — PyPy documentation
じゃあ、これで共有ライブラリをdlopen()すればよいか、とやってみようとしたが、dlopen()が失敗する。。。
pythonだと読めるので、pypyの問題だろう。
フルパスで書いても、なんかInitが付く名前のオブジェクトが見つからないとか、そんなエラーが出たので私は考えるのをやめた。


次に試したのは、cython。
なんて読むんだ?

cythonは、pyファイルの拡張子を変更して、数行のsetup.pyを書いてpythonを実行すれば動く。
動いて、そのpythonファイルをCソースに変換し、soファイルを作る。
それをimportして使うようだった。
チュートリアル基礎編 — Cython 0.17.1 documentation

やってみたが、かなり長い時間がかかって、ちゃんとsoファイルができた。
pythonでimportすると、読める。
おお。

が、だ。
私が変換したのはmainのところで、しかもコマンドラインで引数を渡して動かすタイプだった。
そういうものをimportすると、グローバルのところに書いたprintがちょろっと動くだけだ(当たり前)。
だから、cythonで変換するなら関数単位で使えるようなものがよいのだろう。
importするようなモジュールにしておくと、cythonしやすいだろう。

なんとかsys.argvを引き渡す形式の関数にして、pythonからはリスト形式で引数を渡すように書き換えた。
これはこれで動いたのだけど、別の箇所で例外が発生して動かなかった。
code_funcなんとかとか出てきてた気がするが、もう忘れた。

ダメなパターンがあるのか、チュートリアルの知識だけでやろうとしてるからダメなのかは調べてない。
計算だけしているモジュールもあって、そっちは動いているから、なんかあるのかもしれん。


やろうとしている速度向上が、時間関数を使わないとわからない、とかいうレベルではなく、声を出して「いーち、にーい、・・・」などと数えられるレベルなので、こんな小手先の技では無理だと分かってるんだけどね。

まあ、「あと数歩」という高速化を求めている場合には使えるかもしれんので、覚えておいて損はなかろう。

2017/01/25

[py2]大きい数字を16進数のstrにする

過去にもやったと思うのだが、歳のせいか思い出せないし、探してしまうので、タイトルで分かるようにしよう。

整数型のサイズが、1, 2, 4, 8バイトであればstructを使っていたのだが、3バイト長だったり、32バイト長だったりすると、そうもいかないと思う。

>>> x = 0x0123456789abcdef
>>> x
81985529216486895L
>>> '%016x' % x
'0123456789abcdef'
>>> '{:016x}'.format(x)
'0123456789abcdef'
>>> format(x, '016x')
'0123456789abcdef'

printするときのように%を使ってやっていたのだが、Stackoverflowにformatを使う例が書かれていた。
%を使うのはold styleなのか。。。

2017/01/24

[nfc]Android HCEとWindows10(PC)

前回、AndroidでHCEして動かした。
いずれはきれいに書き直したいのだが、とりあえずNexus5とNexus7(Android 6.0.1)では動いている。

 

ただ、これを読み取る相手がうまくいかない。
NXPのPN7150では、正しく読み取れている。
Androidの画面が表示されていれば、ロック画面でも読み取れるようだ。

ロック画面では搬送波が出ていないので、これであればWindows10でも読めるかと思ったが、今日は動かない。。
AndroidのNXP TagInfoアプリでは1回だけ読めた(Nexus5のHCEをNexus7で読んだ)。
2回目は読めなかったが、普通のNFCタグも読めなくなっていたので、NfcService自体が再起動したんじゃなかろうか。

 

PN7150を使ってみていると、Nexus5のロック画面ではHCEでのタグが、ロック解除するとLLCPが読み取れている。
これはNexus7でも同じようだ。
だから、普通の画面だとHCEが動いていないかもしれんが、ロック画面では動いていそうなのだ。
だったら、Windows10で読めてもおかしくない気が。。。

Androidのログを見ても、アクセスしに来たという形跡がない。
FeliCa Plugで搬送波検知タイミングをLEDで表示させてみたが、読み取れるタグをかざしたときと、HCEしているロック画面をかざしたときの点灯具合が明らかに異なる。
通常は間欠送信で、タグがあると出しっ放しになるのだが、ロック画面をかざしても間欠送信しかしていない。
Windows10に読み取れるタグをかざして搬送波を長めに出させ、ささっとロック画面にしたAndroidをかざすと読み取ってくれた。

 

ということは、うまくHCEのタグを読んでくれないのは、Windows10の粘りが足りないということか。
RC-S380を使っているのだが、NFCポートソフトウェアがインストールされていないせいかもしれないが、もうちょっと長めに出さないとHCEしている端末では間に合っていないのかもしれない。

[nfc]HCEサンプルを久々に動かす

お仕事用にNFCタグを作っていたのだが、そういえばAndroidにはHCEがあったことを思い出した。
HCE...Host Card Emulation。
モバイルFeliCaチップやPN544のようにチップがカードエミュレーションするのではなく、ソフトウェアが制御するカードエミュレーションだ。

 

3年くらい前に作ったものがあった。
hiro99ma blog: [nfc]HCEのサンプルを作った
SDK19だったらしい。
まだAndroid Studioではなかったのでimportして、SDKを22くらいに変更(最新すぎない程度に新しくした)。
PC/SCも少しやったので、当時よりは内容を理解できるかもしれんが、まずは動かそう。

。。。動かん。
そもそも、ActivityがないServiceだけのアプリだから、動いていてもいなくても、よくわからん。
当時はFeliCaランチャーを使ったようだけど、どうせなら普通のR/Wで読込ませたいではないか。

 

そうだ、こういうときにPN7150を使えばよいのだ!
nfcDemoApp pollを起動して、かざすと・・・

Found

Type :          'Type A'
NFCID1 :        '08 20 79 C5 '
Record Found :
                NDEF Content Max size :         '48 bytes'
                NDEF Actual Content size :      '27 bytes'
                ReadOnly :                      'FALSE'
                Type :                          'URI'
                URI :                           'http://hiro99ma.blogspot.com/'

ふん、動いているじゃあないか。

そして、うまく動いてくれなかったWindows10 + RC-S380や、Nexus7のNXP Tag Infoアプリでも読めるようになった。
なんだったんだ。。。

うっとうしいことに、Nexus7にかざすと、Nexus5(HCEアプリはNexus5で動かしていた)の方にAndroid Payの画面が立ち上がってしまう。
対応するクレジットカードを持っていないので、出てきても困るし、そもそもそんなの期待していない。

まあ、動くには動いたので、Android Studio + SDK22版をコミットしておこう。
ランチャーがないので、設定アプリから削除するなりアンインストールするなりになります。
hirokuma/HceSample at 6419f2ad21e4654f7b084e64744eb2b2fc7fc521


GoogleのHCEサンプルを動かしてみたのだが、こっちはSNEPというか、Android Beamっぽく動いてしまう。
googlesamples/android-CardEmulation

 

うーん、便利にしようとしすぎて、よくわからない動きになってしまっている気がしている。
かといって、iOSみたいに何もできないのも困るので、もうちょっと自由度がありつつ、抑えもきかせたいという。。。
もう、専用のハードボタンがあってもよいんじゃないかとすら思ってしまう。

2017/01/23

[nfc]OM5578/PN7150S来たる - おまけ

今さらだが、OM5578/PN7150S Raspberry Pi版の回路図があった。
http://www.nxp.com/documents/software/HW3561.zip

PN7150やOM5578でばかり調べていたけど、直接Raspberry Piに挿すのはOM29110だから、その図面を探さないといけなかったのだな。。。

 

こちらが、OM5578(PN7150が載っているボード)のピン(I2C側は省略)。

image

こちらが、Raspberry Piに挿す方。

image

 

基板のシルクを見ると、GPIO_0がIRQ、GPIO_1がVEN、残りは印刷されていない。
そして、GPIO_0はRaspberry Piの16ピン、GPIO_1は18ピンにつながっている。

 

で、前回のDTSファイル。

&i2c1{
	status = "okay";
	pn547: pn547@28 {
		compatible = "nxp,pn547";
		reg = <0x28>;
		clock-frequency = <400000>;
		interrupt-parent = <&gpio>;
		interrupts = <23 0x0>;
		interrupt-gpios = <&gpio 23 0>;
		enable-gpios = <&gpio 24 0>;
		firmware-gpios = <&gpio 25 0>;
	};
};

あー、interruptsやinterrut-gpiosが23なのは、PN7150のIRQピンがRaspberry Piの16ピンで、それがGPIO23だからか。
VENも、18ピンがGPIO24だから、enable-gpiosも24なのだね。

firmware-gpiosはGPIO25の予定だけど、回路図に書いていないから意味が無いのかもしれない。
OM5578の回路図はこうなっていたので、うん、意味が無いな。

image

 

ドライバのソースを読むと、IRQは必須だけど、VENやFIRMはオプショナルのようだ。
FIRMは、ファームウェアのダウンロード制御に使うようである。

 

LinuxのDevice-Treeのことはわかっていないが、今回の数字がRaspberry PiのGPIOピンと関連していることが分かったので、少しすっきりした。

2017/01/22

[nfc]OM5578/PN7150S来たる (5)

前回、dmesgを確認して、何かエラーになっているところまで分かった。
どうしたものか。。。

01: (irq_create_of_mapping) from [<80498ba8>] (of_irq_get+0x4c/0x5c)
02: (of_irq_get) from [<8044af78>] (i2c_device_probe+0x208/0x224)
03: (i2c_device_probe) from [<8039d008>] (driver_probe_device+0x204/0x2d0)
04: (driver_probe_device) from [<8039d170>] (__driver_attach+0x9c/0xa0)
05: (__driver_attach) from [<8039b1b0>] (bus_for_each_dev+0x74/0xa4)
06: (bus_for_each_dev) from [<8039ca30>] (driver_attach+0x28/0x30)
07: (driver_attach) from [<8039c640>] (bus_add_driver+0x19c/0x224)
08: (bus_add_driver) from [<8039d830>] (driver_register+0x88/0x108)
09: (driver_register) from [<8044c278>] (i2c_register_driver+0x48/0x8c)
10: (i2c_register_driver) from [<7f0e9024>] (pn54x_dev_init+0x24/0x38 [pn5xx_i2c])
11: (pn54x_dev_init [pn5xx_i2c]) from [<80009754>] (do_one_initcall+0x90/0x1f0)

バックトレースまで出ていて、この辺がポイントなんじゃなかろうかとは思うのだが、見方がさっぱりわからん。

pn54x_dev_initはgithubから落としてきたソースに入っている。
また、このログの後にこう出ている。

01: pn54x_probe
02: /soc/i2c@7e804000/pn547@28: could not get #gpio-cells for /soc/cprman@7e101000
03: pn544 1-0028: VEN GPIO error getting from OF node
04: pn544: probe of 1-0028 failed with error -22

よくわからんが、OF nodeとかいうやつが関係しているらしいから、of_irq_getがうまくいかないとか、そんなことだろうか。
検索してみた。

Raspberry Pi • View topic - AR1021 Touch Controller Overlay/Driver Issues

この人も、同じようにエラー-22で、I2Cで、of_irq_getのログが出ている。
アドバイスで「"interrupt-parent"を正しくせよ」と書かれている。

今使っているDTSの設定は、NXPが提供しているDTBファイルから持ってきたものだ。
kernelが違うので、interrupt-parentを変更しないといけないということかもしれない。
<0xf>という値は、動いているDTSファイルを検索すると、bcm2835-gpioのphandleというものと同じ値のような気がする。
今のDTSファイルでは、bcm2835-gpioのphandleは<0xb>になっていた。

では、と、pn7150のDTSファイルで<0xf>を<0xb>に変えてみた。

01: pn54x_dev_init
02: pn54x_probe
03: pn544 1-0028: CLKREQ GPIO  error getting from OF node
04: pn54x_probe: request irq_gpio 23
05: pn54x_probe: request ven_gpio 24
06: pn54x_probe: request firm_gpio 25
07: pn54x_probe : requesting IRQ 189

おお、バックトレースが出なくなった!
出なくなったが、OF nodeのエラーは出ている。。。
nfcDemoAppを動かしても、コールバック関数登録のエラーが出て動かない。

エラーは、ここだろう。
https://github.com/NXPNFCLinux/nxp-pn5xx/blob/master/pn5xx_i2c.c#L460

OPTIONALと書いてあるから、もしかしたらオリジナルでもエラーになっているかも・・・出てた。
ということは、それ以外の原因で動いていないのか。。。


NXPのkernelでnfcDemoApp pollするとpn54_dev_open()が呼ばれているログがdmesgに出るのだが、私のkernelでは出てない。
lsmodでpn5xx_i2cは出てるし、/dev/pn544はあるし、何が不満なのだ?

 

出ているのは、このエラーだろう。
https://github.com/NXPNFCLinux/linux_libnfc-nci/blob/master/demoapp/main.c#L665
たどると、nativeNfcSnep_registerClientCallback()だとは思うが、エラーログすら出てないので、さっぱりわからん。
トレースログはsrc/halimpl/pn54x/log/phNxpLog.hのマクロをTRUEに変更せんといかんようなので、リビルド。

NxpFunc:    nativeNfcManager_doInitialize: enter; NCI_VERSION=0x10
NxpFunc:    nativeNfcManager_doInitialize: can't find libnfc-nxp.conf file
NxpFunc:    nativeNfcSnep_registerClientCallback:
NxpFunc:    nativeNfcSnep_registerClientCallback: Nfc not initialized.
SNEP Client Register Callback Failed

意外ッ! それは設定ファイル!!
どうも、/etc/libnfc-nxp.confを読みに行っているようである。
ファイル自体はこれを置けばよいのか。
make installしてもコピーされないので、わからんよ。。。
https://github.com/NXPNFCLinux/linux_libnfc-nci/blob/master/conf/PN7150/libnfc-nxp.conf

ファイルを置いて、ついでにLD_LIBRARY_PATHに/usr/local/libを追加した。
今度実行すると、先に進んだが、I2Cのオープンに失敗しているようだ。

NxpTml:     Opening port=/dev/pn544
NxpTml:     _i2c_open() Failed: retval ffffffff

I2Cは/dev/i2c-1だと思うが、/dev/pn544とつながっているのかな?
試しに

$ cat /dev/pn544

とすると、Permission deniedで怒られた。
ということは・・・

$ sudo ./nfcDemoApp poll

おー、動いた!
ログが大量に出てわからんが、搬送波も出ているし、かざすとログが出るので、読んでいるのだろう。


では、Raspberry Pi2の自分のkernelをビルドし、OM5578/PN7150Sを動かすようにするまでの手順を残しておこう。
もっとスマートなやり方があるとは思うのだが、今の私ではこれが限界だ。

  • Raspberry PiのKernel buildingを見ながら、ビルドする環境を作る。
    うちは、Bash on Windowsでやった。
  • AN11697のPDFの3章を見ながら環境を作る。
  • 3.2.3章のデバイスノードは、Device treeの方にする。
    私はこの内容をnxp-pn5xx.dtsという名前で、arch/arm/boot/dts/に置いた。
    数字は、NXPのkernelからDTBファイルをDTSに変換して持ってきた。
&i2c1{
	status = "okay";
	pn547: pn547@28 {
		compatible = "nxp,pn547";
		reg = <0x28>;
		clock-frequency = <400000>;
		interrupt-parent = <&gpio>;
		interrupts = <23 0x0>;
		interrupt-gpios = <&gpio 23 0>;
		enable-gpios = <&gpio 24 0>;
		firmware-gpios = <&gpio 25 0>;
	};
};
  • arch/arm/boot/dts/bcm2709.dtsiファイルに、「#include "nxp-pn5xx.dts"」を追加。
    これだと、Raspberry Pi2のDTSファイルにしか読み込まれないので、bcm2708_common.dtsiに追加した方がよいかもしれない。
    また、nxp-pn5xx.dtsにしたものの、includeするから拡張子はdtsiの方が良いのかも。
    ルールがよくわかってない。
  • Raspberry Piのサイトを見ながらkernelをビルドする。
    DTBファイルを作るだけなら、make ~ dtbsだけ実行するとarch/arm/boot/dts/にDTBファイルができるので、それでよいだろう。
  • ビルドしたものをRaspberry Piのサイトを見ながらSDカードに展開する。
    DTBファイルだけなら、SDカードにコピーするか、動いている環境から/boot/にコピーする、でよいだろう。
  • ここまででよいはずなので、Raspberry Piを起動し、dmesgを見る。
    "dmesg | less"などとして、"pn"を検索するのがよいだろう。
    エラーになっていないなら、たぶん大丈夫。

次は、デモアプリ。
Raspberry Piでビルドする前提。

  • githubからlinux_libnfc-nciをgitで取ってくる。
  • ./bootstrap
  • ./configure --enable-pn7150
  • make -j4 (jの数はてきとう)
  • sudo make install
  • conf/PN7150/libnfc-nxp.confを/etc/にコピー
  • LD_LIBRARY_PATHに/usr/local/libを追加
  • sudo ./nfcDemoApp pollなど

たぶん、こんなもんじゃなかろうか。
つかれたー。

2017/01/21

[nfc]OM5578/PN7150S来たる (4)

PDFに従い、make defconfigして.configを作った。
menuconfigするのが面倒だったので、.configをPNで検索して書き換えた。

CONFIG_NFC_NXP_PN5XX=m

そして、zImage, modules dtbsする。
時間がかかってビルドできたので、書いてあるようにSDカードにコピーする。
私はBash on Windowsでやったので、適当にtgzに固めて、scpでコピーしてRaspi上で書き換えた。

起動!
・・・だめだ、koファイルはできているのだが、読込んでくれる気配がない。。。

 

問題は、DTSファイルの方ではないだろうか?

試しに、arch/arm/boot/dts/に、"Hello!"と書いたaaaaa.dtsファイルを置いて、make dtbsしてみた。
エラーにも何もならない。。。
読んでくれてすらいないということか。


じゃあ、今動いているkernelはどうやってるんだろうか。
もしかして、=mじゃなくて、=yしてkernelに入れ込んでるんじゃなかろうか?
だからといってDTSファイルが不要だとは思わないけど、kernelに組み込んでいるからdtbに入っている、とかか?
それだったらoverlaysに入っているのかもしれんが、そういう訳でもない。
DTSがわかってないのに、適当にやろうとするのが間違いなのか。。。

 

まあいい。
まずは、動いているkernelと同じconfig設定にしよう。

Raspberry Pi 2で現在のカーネルのコンフィグを確認する - 組み込みの人。

これでconfig.gzを取り出して、見てみた。

CONFIG_NFC_NXP_PN5XX=y

ビルドし直して動かしたが、そういう話ではなさそうだ。


動いている環境のdtbを見直したが、pn7120の部分はi2c@7e804000というところの中に入っているのだ。
入れ子になっているから、includeとかしてるんじゃないだろうか?

適当の書き換えて、raspi2のdtsにincludeしたら、それっぽいdtbファイルになった。


とにかく、アプリを動かさないと分からない。

https://github.com/NXPNFCLinux/linux_libnfc-nci

git-coreをapt installし、上記をgit cloneして、./bootstrapして足りないものをapt installして、

$ sudo apt install git-core bc automake autoconf libtool
$ ./configure --enable-pn7150
$ make
$ ./nfcDemoApp

立ち上がりはするのだが、SNEPのコールバック関数登録ができないというログが出るし、なによりタグをかざしても反応がない。

失敗だ!

 

/dev/を見ると、/dev/pn544がない。
lsmodではpn5xx_i2cが見えるのだが、あればよいというわけではないのか。
configを見比べたが、動いている方でもNFCは有効<m>になっているものの、CONFIG_NFC_NCIなどは未設定になっている。
CONFIG_NFC_PN533は<m>だけど、これは関係ないよなぁ。
CONFIG_BCM2708_GPIOが今回のconfigにないのがあやしい気もするのだけど、そもそもPDFではkernelの設定については触れられていないので、さっぱりわからん。。。

$ dmesg
....
pn544: probe of 1-0028 failed with error -22
...

あー、ドライバでエラーが出てるんだ。

2017/01/20

[nfc]OM5578/PN7150S来たる (3)

では、Raspberry Piのkernelをビルドして、一緒にnxp-pn5xxもビルドしよう。

 

ここからが、いろいろ分からなかった。。。

Raspberry Piのkernelビルド自体は、説明ページもあり、クロスコンパイルのことも書かれているので、よい。
Kernel building - Raspberry Pi Documentation

nxp-pn5xxをkernelのソースに組み込む方法も、こちらのPDFに書かれていた。
https://github.com/NXPNFCLinux/linux_libnfc-nci/blob/master/doc/AN11697%20-%20PN71x0%20Linux%20Software%20Stack%20Integration%20Guidelines.pdf

じゃあいいやん、と思ったのだが、デバイスの情報がいるではないか。
上記PDFの、"3.2.3 Creating the device node"のところだ。
サンプルもあるくらいだから、Device treeを使うのだろう。
nxp-pn5xx/sample_devicetree.txt at master · NXPNFCLinux/nxp-pn5xx

regはI2Cアドレスだろうから0x28でよいだろうし、clock-frequencyもI2Cだからこのままでよいだろう。
問題は、interrupt-gpiosとenable-gpiosだ。
ドキュメントに、どう設定すべきか書いてある箇所を見つけられなかったのだ。
テスターで当たってみると、たぶんVENが18ピン、IRQが16ピンになっているのだと思う。
が、どう書いてよいのかがわからん。。。

/bootにdtbファイルがあることが分かったので、これを変換してdtsファイルにした。
[Linux][kernel] Device Tree についてのまとめ – Qiita

pn7120@28 {
        compatible = "nxp,pn547";
        reg = <0x28>;
        clock-frequency = <0x61a80>;
        interrupt-parent = <0xf>;
        interrupts = <0x17 0x0>;
        interrupt-gpios = <0xf 0x17 0x0>;
        enable-gpios = <0xf 0x18 0x0>;
        firmware-gpios = <0xf 0x19 0x0>;
        linux,phandle = <0x29>;
        phandle = <0x29>;
};

Raspberry Pi2っぽいdtbファイルを選んだのだけど、たぶんどれも同じよね。。。
githubのサンプルより項目が多いのだけど、全部書いた方がよいのだろうか?
あるいは、自動で埋めてくれるから書かない方がよいというタイプだろうか。。。

悩むねぇ。

2017/01/19

[nfc]OM5578/PN7150S来たる (2)

PN7150は、これだ。
PN7150|High Performance Plug'n Play NFC for OS|NXP

NCI1.0互換というところが売りのようだ。
NFC Controller Interfaceの略なのだが、NCIの仕様書はNFC Forumの有料会員になるか購入するかしないと入手できなくなってしまった。

が、NCI1.0のときはまだダウンロードできたので、手元にある。
以前ダウンロードできたものが有償になったときって、ダウンロードしたものの扱いはどうなるんだろう?
まあ、捨てないけどさ。


PN7150に戻ろう。
PDFを見ると、PCD(R/Wね)にもなれるし、PICC(タグね)にもなれるようだ。
PN53xみたいなチップなのかもしれない。
PN54系は使ったことが無いが、モバイルFeliCaチップみたいに電源だけ入れておけばCardEmulationしてくれるのだろうか。
まあ、私には手に入れられないチップだから、気にすまい。。。

ブロック図を見ると、Cortex-M0が載っていた。
へー。
CODE側とDATA側にそれぞれEEPROMが載ってるのは何でだろう?
ホストとはI2Cで通信するようだ。


そういえば、今のLinuxはNCI対応しているということだ。
I2Cはどうやってるのだろう、などと思っていたが、kernelのビルド時に決まっているのだろうか?

このPDFを見ると、kernel spaceのドライバと、user spaceのHALで何とかしているように見える。
linux_libnfc-nci/doc at master · NXPNFCLinux/linux_libnfc-nci

image

 

lsmodすると、pn5xx_i2cというモジュールが読み込まれていた。
PN7150だけど、pn5xxで扱えるようになっているのだろう。

ソースはこれか。
ちょっと見たけど、よくわからん。
NXPNFCLinux/nxp-pn5xx: NXP's NFC Open Source Kernel mode driver

$ cat /sys/bus/i2c/devices/1-0028/name
pn547

この0028が、0x28というI2Cアドレスということだろうか?

UM10936によると、PN7150のI2Cアドレスは0x28~0x2Bで、アドレスピン2本で決定されるようになっている。
OM5578/PN7150Sの回路図ではどちらのピンもGNDにプルダウンされているから、0x28でよいはずだ。

しかし、これは機器を接続するまで分からないはずだ。
モジュールのビルド時に決定しているのだろうか?
今回使ったRaspberry PiのSDカードはPN7150用だから、そうなのかもしれない。

 

いくらモジュールやアプリが提供されていても、使うまでの方法が分からねば意味が無いのだ。。。
次はそこら辺を見ていこう。

2017/01/18

[nfc][raspi]OM5578/PN7150S来たる (1)

CQ出版のInterface誌にあった、NXPのプレゼントに応募したら当たった。
ありがとう!

今日、届いた。

image

 

モジュールは、こうなっている。

image

 

ものは、こちらだ。

NFC Development Kits for Arduino and more|NXP

"Arduino and more"の、moreは、Raspberry PiとBeagle Bone Blackで、これはRaspberry Pi版だ。
細かい名称は「OM5578/PN7150RPI demo kit」のようである。

一番上のボードが本体で、OM5578/PN7150S。
PN7150というNFC Controller Baoardのようだ。

その下の基板が変換用で、これはOM29110RPIと呼ぶようである。
立派な足とピンが付いているが、この足があるとRaspberry Pi(ノーマル)だと部品が当たって載せられない。
足を外してくれ、とPDFには書かれていた。

面倒だったので、今回はRaspberry Pi2を使っている。


使い方というか、デモの動かし方を載せておこう。

まず、Raspberry PiのSDカードイメージをダウンロードする。
今日(2017/01/18)の時点では、OM5578-PN7150S_Rpi_Linux_demo_v1.1.zipだった。
https://nxp.app.box.com/v/OM5578-PN7150RPI-Linux

これはRaspberry Piの公式ページが配っているのと同じ形式のimgファイルのようで、公式ページに載っているやり方でSDカードに展開するとよいだろう。

うちはだいたいUARTでRaspberry Piをつないでいたのだが、このボードは全部ピンをふさいでしまうので、まずはボードを載せる前にUARTで起動して、WiFiの設定をしてSSHでログインできるようにしてからボードを載せた。
HDMIやキーボードなどで動かせるなら、その辺は気にしなくてよいかも。

 

あとはAN11758(PDF)に載っているようにやっていけばよい。
立ち上げても特にアプリが起動するわけではないので、コンソールから操作することになる。

が、このボードはI2C制御するのだが、デフォルトではI2Cが無効になったままかもしれない。
sudo raspi-configでI2Cを有効にするとよかろう。
今回使ったimgだと、「9 Advanced Options > A7 I2C」でOKにすればよい。

そしてもう1つ。
LD_LIBRARY_PATHの設定がないようで、そのままだと共有ライブラリがないというエラーになった。

export LD_LIBRARY_PATH=/usr/local/lib

などとするとよいかな。

 

"nfcDemoApp"はパスがあるところに置かれているようで、引数を付けて実行すると動く。
たとえば、pollだとこうなる。

image

付属するカードをかざすと、こうなる。

image

 

インストールされているアプリは、/home/pi/linux_libnfc-nciに入っているようだ。
githubにも上がっているようである(PDFはリンク先が切れているのだ)。

https://github.com/NXPNFCLinux/linux_libnfc-nci

 

しかし、このアプリってどうやってRaspberry PiのI2Cを使ってるのだろう?
I2Cを無効にすると「NfcService Init Failed」と出てくるから、/dev/i2c-1を使っているとは思うのだが。

2017/01/17

[win10]USB接続HDDを取り外したい

最近、ノートPC用に外付けHDDを購入した。
内蔵SSDだと小さいので、どうでもよいデータなんかは外に出しておきたいのだ。

それはよかったのだが、一度取り付けると、USBメモリのように取り外しができない。
グレーアウトしているのだ。
Explorerのコンテキストメニューでも「取り外し」は出てこない。

image

ただ、デバイスマネージャではこうなっている。

image

さて、これを信用して取り外してよいものか・・・。

いや、ここは逆に考えて、「高パフォーマンス」設定にして取り外しを有効にさせればよいのでは?とやってみたが、グレーアウトしたままだった。

 

こういうときは、アプリを使うのがよかろう。
今回はこれを試した。

USB Disk Ejector | Quick And Easy Software

image

これで外したいデバイスをダブルクリックすると、外れてくれた。
うちの環境では、これでよさそうだ。

 

まあ、こういうのはデバイスによって変わるかもしれんし、OSのアップデート程度で変わるかもしれんので、ネットで検索するときも直近の情報に絞った方がよいですな。
Googleだと、ツール>期間指定、から選べるので、いつもそうやってる。

image

[hw]買いやすいUART-USB変換ケーブル(2017.01)

3.3VのUARTを、PCのシリアルで見たいことがしばしばある。
でも、PCのシリアルはRS-232Cなどだから、電圧が全然違うし、極性も違う。
だから、電圧の変換や極性の変換が必要になる。

そこまで変換するなら、シリアルじゃなくてUSBでつなげるようになっていてほしい。
という要望があるからだろう、そういう製品は多い。

いま、うちにあるのは、CP2102が載ったモジュールと、PL2303が載ったケーブルだ。
PL2303は、Windows8から古いものがドライバ提供されなくなったのだけど、ごまかしごまかし使えている。

昨日、手持ちのUART-USB変換ケーブルが壊れていたので、買い足すついでに、最近(2017/01/16)の状況を調べておこう。


壊れたのは、CP2102が載ったモジュールの方だ。
これは、aitendoさんから購入したもので、もう6年くらい使っている。
今回はこれを買い足すことにした。

USB-UART変換モジュール – aitendo

税別600円と、お手頃だ。
うちにあるのは、ここの「終了版1」だ。
お世話になりました。

ピンが出ているので、そのままケーブルがあれば挿すこともできるし、ブレッドボードにざくっと挿すこともできる。
まあ、ブレッドボードに挿した場合はUSBの口が上を向くので、延長ケーブルがいることだろう。


秋月通商さんのこちらも、600円だ。

超小型USBシリアル変換モジュール: 半導体 秋月電子通商 電子部品 ネット通販

こちらは、microBケーブルを使って挿すことになる。
5Vトレラント・・・というのは、5VでもRXDに突っ込めるということを意味しているようだ。
Arduinoからログ取りだけしてい、なんてときでも使えるということだろう。
こちらは、少し値段が上がるが、5V/3.3Vの切替ができるようだ。
FT-232RQ USBシリアル変換キット: 半導体 秋月電子通商 電子部品 ネット通販

また、FTDIのチップを使っているというところもアピールポイントだろう。
FTDIのチップを使ったものは高めになる傾向があるようなので、これはうれしいところだ。


スイッチサイエンスさんのこちらは、値段が上がるが、3.3V/5Vだけでなく、細工をすれば1.8Vでも使えるとのこと。

FT231XS USB-シリアル変換ボード - スイッチサイエンス

 

そして、こちらの古いタイプが、うちにあるもう1本の変換ケーブルだ。

USBシリアル変換ケーブル – スイッチサイエンス

PL2303の古いタイプは海賊版が出回ったためにドライバの提供を止めてしまったらしい。
まったく・・・。
ストロベリーリナックスさんのところは、そっちのタイプのようだ。

OLIMEX USBシリアル変換ケーブル(3線式) - USB-SERIAL-CABLE-F - ネット販売


私が使っているお店は、だいたいこの3つだ。
他にもいろいろあるのだけど、探すと切りが無いのでね。。。

2017/01/15

AzureでMQTT brokerを立てようとする (4) - 最終回

最初に書いておこう。
Azure IoT HubはMQTTをサポートしているが、MosquittoのようなMQTT brokerではなさそうだ。
あくまで、Azure IoT Hubへの通知や、IoT Hubからの通知としてMQTTをサポートしているだけであって、topic名をsubscribeしたからといって、そこにpublishしても配信されないようだ。

IoT Hub の MQTT サポート | Microsoft Docs
ここの下の方に書いてあるが、トピック名は

  • デバイス→クラウド(publish):devices/{device_id}/messages/events/
  • クラウド→デバイス(subscribe):devices/{device_id}/messages/devicebound/#

となっている。
publishするときは、お尻の「/」もいるようだ。

 

だから、タイトルのように「AzureでMQTT brokerを立てる」ということをしたかったら、VMを作って、そこにMosquittoなどをインストールすることになると思う。


これで終わりにしてもよかったのだが、pythonからpublishするくらいまではやっておきたい。

昨日、TLS接続はできてon_connect()がコールバックされるのは確認できたのだが、どうも接続拒否されているようだった。
result codeが5で返ってきているのだ。
だから、on_connect()が何度も呼ばれているのだろう。

Client(client_id, protocol=MQTTv311), username_pw_set()。
TLS以外はこんなものだと思うのだけど、他に設定がいるのだろうか?

動いているMQTTBoxの設定と見比べても、特におかしなところはない。
usernameの"/api-version=2016-11-14"は、あってもなくても接続できるようだ。
では、なぜ・・・・・・・

 

ああ、MQTTBoxと同じデバイスIDを使っているからか。
DeviceExplorerで新しくデバイスIDを作り、SAS tokenなんかもそっちの設定にしたら接続できた。
subscribeもできている。topic名が長いな。。。

 

というわけで、これで終わりにする。

AzureでMQTT brokerを立てようとする (3)

そういえば、TLS/SSLって、サーバがはじくためじゃなくて、クライアントがはじくための通信だったような気がする。
サーバがクライアントをはじく場合は、Basic認証とか何とか認証とか、そういうのでやったような記憶が。。。

 

pythonのpaho.mqtt.clientで、tls_insecure_set(True)を呼び、tls_set('xxx.crt', cert_reqs=ssl.CERT_NONE)した。
crtファイルは、前回失敗したものをそのまま使っている。空文字列だとエラーなのだ。

そうすると・・・on_connect()がコールバックされた!
たぶん、まともなやり方ではないのだけど、CRTファイルを指定せずにTLS接続するというのはこういうことじゃないだろうか?
(ストアアプリの場合は、Windowsに登録してあるものを使ったのかもしれん。)

 

Linux上で動かすサンプルも見かけたのだが、そちらは/etc/ssl/certsにあるファイルを指定していた。

This is a simple example showing how to use the [Paho MQTT Python client](https://eclipse.org/paho/clients/python/) to send data to Azure IoT Hub. You need to assemble the rights credentials and configure TLS and the MQTT protocol version appropriately.

そういうのがWindowsにもあれば試すんだけどねー

・・・あ、Bash on Windowsがあった。
lsしてみると、同じ場所にファイルがあったので、pythonのスクリプトと同じ場所にコピーして、tls_insecure_set()を消し、tls_set('ca-certificates.crt')だけにして動かした。

動くやん。


とりあえず、これでpythonのpaho.mqttからAzure Iot HubにMQTT connectまではできたと思う。
ただ、on_connectのコールバックが呼ばれ続けるのよね。。。
Mosquittoのときはそうではなかったので、なんかしてやらんといかんのか。
on_messageなど、普通に使うコールバックを登録していないとか、subscribeするトピックを登録していないとか、そんな理由だろうか。

2017/01/14

AzureでMQTT brokerを立てようとする (2)

AzureでIoT hubを立てるところまでできたのだが、デバイスの登録で止まっている。
ツールをインストールしたり、アプリを作ったりすれば登録できるようなのだが、もっと手軽にやりたい。
そもそも、Azureの設定画面にログインしてるのだから、そこからできるようにしてないのは需要がないからだろうか?

 

わからない。。。
敗北感が強いが、DeviceExplorerを使おう。

Releases · Azure/azure-iot-sdks
DeviceExplorerというツールは、今はここにあるようだ。

ツールの使い方は、こちらが詳しい。
Azure IoT Hubを使ってみた - Qiita
リンク先がいろいろ変わったようだが、元の情報はこれかな?
azure-iot-sdk-csharp/tools/DeviceExplorer at master · Azure/azure-iot-sdk-csharp

今のツールは、この画面からSASトークンも作ることができるようだ。

image

試しに、mqtt1というデバイスIDを登録し、SASトークンを作ってみた。
これ、Generateを押すたびに作ってくれるのだけど、一番最後のsigとseだけが変わっているようだ。

image

 

これで、ここに書かれている情報は揃ったことになる。
MQTT プロトコルの直接使用

が、パスワードがわからん。
SASトークンを使うらしい。

SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}

日本語だと表示が変な気がしたので、英語版を見てみた。
Using the MQTT protocol directly

ちょっと内容が違う・・・。

  • ClientId = deviceId
  • Username = {iothubhostname}/{device_id}/api-version=2016-11-14
  • Password : SAS token

それに、SharedAccessSignatureがsig, se, srの順で書いてあるけど、下に書いてある説明ではsr, sig, seの順だ。
SAS Tokenで生成したものもその順になっているから、そっちが正しいのだろう。

ESP8266, Arduino & Azure IoT Hub
こちらは、ESP8266でつないだときのことが書かれていた。
ポートは8883でTLS接続、ClientIdはデバイスIDで、UserNameはapi-versionが無く、Passwordは"SharedAccessSignature"で始まる文字列になっている。

 

お、WindowsのMQTTクライアントで接続できた!
api-versionは付けている。
スマホのMQTTクライアントは接続できないな。。。何が違うのか。。。

 

pythonのpaho.mqttでやってみると、TLS接続のハンドシェイクで失敗しているようだ。

ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)

ここにあった、一番下のCERTをファイルにしてみたが、ダメだった。
https://docs.microsoft.com/ja-jp/azure/app-service-web/java-create-azure-website-using-java-sdk#create-a-certificate

keytoolでcertファイルを作って試したが、やっぱりダメ。
作ったcertファイルをAzureに登録するような操作がいるのだろうか?

動いているMQTTクライアント(MQTTBoxというストアアプリ)は、ストアアプリだからAzureと相性が良さそうだしなぁ、などと勘ぐってしまう。
TLSはv1でもv1.2でも接続できるから、あとはCertificate Typeくらいか。
アプリの設定は「CA signed server certificate」というやつにしたのだが(これ以外だとファイルの指定がいるから)、これが何をしているのか分かればなぁ。

うーん、今回はここまで。

AzureでMQTT brokerを立てようとする (1)

お仕事で、クラウド上にVMを作る、というのをやった。
なんとなくAWSが有名な気がするが、使ったのはMicrosoft Azureだ。
あらまあ便利だわねぇ、と感心した。
いや、AWSに比べて、とかではなく、単純にOSのインストールとか面倒なことをせずに済む、という意味でだ。

家でも使えると便利かもしれんと思って調べると、30日間無料だった。
まあ、ずっと使うならお金がいるよねぇ。。。と思ったら、無料枠があった。

価格サービス | Microsoft Azure

VMなんかは入っていないが、いろいろと使えるようだ。
IoT Hub、というのもあるし、これだったらMQTT brokerになってくれるんじゃなかろうか?ということでやってみることにした。


そもそも、IoT HubでMQTTがあるのか?という疑問があったが、サポートしているようだ。

IoT Hub の MQTT サポート | Microsoft Docs

試しに1つ作るとき、名前に「mqtt」と付けると「付けられません」というエラーになった。
名前を自由に決められないのか?と不思議に思ったが、その名前を使ってホスト名を作るため、既存のものは使えないというだけのことのようだ。

(なまえ).azure-devices.net

こんなホスト名になる。

 

で、作ったものの、これからどうしてよいのかわからない。。。
ホスト名があるのでpingやnslookupしたけど、解決できないのだ。
pingは止められているだけかもしれんが、名前が解決できないとどうしようもない。

あ、ネットの名前解決サービスを使うと見つけられた。
IW3 PROJECT DNSによる名前解決サービス

image

なるほど、そういうことか。
今回はFreeのものを使ったからかもしれん。
なお、Freeのものは1つしか作ることができないとのこと。

image

30日間は2万円くらいまで使えるので、S1 Standardのものも作ってみた。
うん、名前解決すると同じIPアドレスになった。

 

あれ、MQTTでつなぐとして、IPアドレスが同じだったらどうやって見分けるのだろうか?
何かしら、IDなり登録なりして通知しないとわからんだろう。
どうやるのだ?

Azure IoT Hub の使用 (Java) | Microsoft Docs
使い方のページがあった。
これはJavaだが、他に.NETやNode.jsのページもある(Node.jsは「ノード」とカタカナ表記になっていた)。

「共有アクセスポリシー>iothubowner」というページで、共有アクセスキーを見るようだ。
「主キー」なのに「セカンダリーキー」で「接続文字列—プライマリキー」なのは愛嬌だろう。
接続文字列の欄は、HostName, SharedAccessKeyName, SharedAccessKeyがひっついているだけのようだ。

で、ここから「Settings > Messaging」に相当するページに移動することになっているのだが、どこなんだ。。。
「設定」じゃなくて、トップメニューの下の方にあった。

image

ここの「Endpoints」の「Built-in endpoints」一覧の「Events」をクリックすると、それっぽい画面が出てきた。
これでいいのだろうか。。。

いや、それ以前に、MQTTで接続するのに何が必要なのかを先に調べるべきだ。
MQTT プロトコルの直接使用

  • ClientId = デバイスID
  • UserName = {ホスト名}/{デバイス名}
  • Password = SASトークン

という対応になっているとのこと。
ならば、デバイスIDを作ればなんとかなるのかもしれん。

 

デバイス ID の作成
・・・Java版だからだと思うが、Javaアプリを作らないといけないのか?
「概要」の上に「デバイス」があるから、ここから追加できるのかと思ったが、押せない。

image

ハブの作成と Raspberry Pi 3 の登録 | Microsoft Docs
ここを見ると、Azure CLIというツールを使って追加するようなのだが、クライアントからできるならWebからだってできておかしくないのでは。。。

Azure IoT Hubでデバイスを管理する - Qiita
どうやら、デバイスを登録するとメニューが有効になっているようだ。

Azure/iothub-explorer: IoT Hub Explorer is a tool that allows you to explore and test Azure IoT Hub features
ツールも提供されている。
されているのだが。。。

いやだー、私はWebで全部済ませたいんだー!

2017/01/13

[nfc]AndroidでFeliCa Liteを読む

AndroidでFeliCa Liteを読むアプリを作っておこう。
すごいことをやっているわけではなく、2年くらい前に作っていたclassを多少手直ししただけだ。

https://github.com/hirokuma/AndroidFelicaLiteRead2016

 

画面に何も出ず、Logcatで出力させるだけにしている。
このくらいシンプルだったら、アプリのソースを読むのも大変じゃなかろう。

NfcFactoryは使いそうなものをAPIにしただけで、必須ではない。
FelicaLiteが本体なのだが、MifareUltralightみたいな継承で作ることができなかったのが心残りだ。

2017/01/12

[rpi]Raspberry PiでFeliCa Linkを動かす (4)

結果としては、Raspberry Pi + RC-S730は動いた。
いや、動いていた、というのが正しい。

今まではNFC R/WとしてNexus5のTagInfoアプリ(NXP製)を使っていた。
しかし、何か嫌な予感がして自分で作ったFeliCa Lite読込みアプリを使うと、読めた。

そう書くと、Androidアプリの書き方に特徴があるのではないかと思ってしまいそうだが、いやいやいや。。。
私は仕様書通りに、しかもAndroidのAPI仕様に従って作っているだけなので、特に技は無いと思うのだ。
MIFAREみたいに便利なAPIがあるわけでもないので、NfcFで地道にやっているだけ。

それに、NXPのTagInfoアプリだって、普通のFeliCa Liteは読めるし、FeliCa LinkにしてもPlugモードじゃなくてカードとしてアクセスできる状態にしておけばアクセスできていたと思うのだ。

 

じゃあ、一体何が違うのか・・・。
DDMSのログを見ると、TagInfoなんかで読めないときはドライバだかJNIだか忘れたが、あの辺でタイムアウトが発生していた。
でも、FeliCa Linkで設定できる時間はPMmくらいしかないと思うし、あれも0xFFだったので最大値のはずだ。
それに、ドライバでダメなのなら私のアプリでもダメなはずじゃないか。
ログからはそれ以上の情報が読み取れない。

よくわからんが、R/W側に原因があったということで、Raspberry Piの方は終わりにしよう。
github

2017/01/11

[rpi]Raspberry PiでFeliCa Linkを動かす (3)

ロジアナを持ってきて、カード読み出し時のFeliCa Linkのピンを見てみた。

image

下から順に、RFDET、IRQ、I2Cたち、となっている。

やっぱりというか何というか、RFDETとIRQがまったく同じ動きをしている。
なんで「やっぱり」と思ったかというと、RFDETに接続したLEDの点灯とIRQ立ち下がりのコンソール出力が同じくらいのタイミングだったからだ。

 

ハンダ付けミスかと思ったが、なんと原因はFFCケーブル。
なぜか、接点部がぐちゃぐちゃになっていたのだ。
なんとも初歩的なミスよ。。。

ぐちゃぐちゃになっている部分を切断してきれいにすると、ショートが直った。


これで動くようになったかと思ったが、甘かった。
今度は、IRQが立ち下がらないのだ。
切断したせいかもしれんと思ったが、別のFeliCa Linkで試しても同じだった。

うーーん・・・。

RFDETとショートしているときにはアプリも動いたので、立ち下がればコンソールに出てくれることはわかっている。
念のため、RFDETをRaspberry Piに挿してみたが、搬送波検知でログが出るし、ちゃんとロジアナも立ち下がりで反応している。

だから、FeliCa LinkがIRQを下げる必要がないと思っているのだろう。
先は長そうだ。。。

2017/01/09

[rpi]Raspberry PiでFeliCa Linkを動かす (2)

前回の続き。

FeliCa Linkの搬送波検知は使わず(LEDが自動で点灯)、IRQ立ち下がりでI2Cアクセスするだけの予定だ。
Read without Encryptionは実装しよう。
Write without Encryptionがあると、メモリアドレスをレジスタのように使ってR/Wから要求を出すことができるのだけど、無理はすまい。

前回はmbed用に作ったライブラリ(C++)からCに移植しようと考えていたのだが、そういえばnRF51用に書いたものがあった。
そちらを使おう。

https://github.com/hirokuma/nrf51822_felicalink_v810/tree/master/felica


そういえば、スタートコンディションやストップコンディションの制御はどうやって行うのだろう?
writeの場合は書込むだけだからよいのだが、readはレジスタを指定した後に読込むので、ストップコンディションを発行しないwriteをしたいのだ。

 

これだ、というのは見つからんのだが、i2c_smbus_read_block_data()なんかでできるのか?
https://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/include/linux/i2c-dev.h

でも、これはこれで、readしたデータの先頭がデータ長になっている前提のようにも見える。
そもそも、引数に読みたいデータ長を指定するようになっていないので、これはこれで困る。。。

 

Raspberry Pi で I2C の Repeated Start Condition を有効化 - Rabbit Note
これだ。
Repeated Start Conditionっていうんだ。
「ストップコンディションを自分で制御する」ではなく、「続けてスタートコンディションを発行する」という見方になるのか。
ストップコンディションは一連の処理が終わるまでやらないものかと思っていたが、そうじゃないデバイスもあるんだな。

sysfsに書込めば動的にも設定できるそうだ。
I2C Repeated Start

sudo sh -c '/bin/echo Y > /sys/module/i2c_bcm2708/parameters/combined'


あとは、ファイルをRaspberry Piに送る方法が必要だった。
これは、WinSCPを使ってSFTPでやればよいだろう。

。。。と思ったら、SSH自体が使えなかった。
SSH (Secure Shell) - Raspberry Pi Documentation

$ sudo raspi-config

ここで「5 Interfacing Options」を選び、次の画面で「P2 SSH」を選択。
Enableにするか聞かれるので、Yes。

これだけで、TeraTermからSSHすることができた。
WinSCPもOK。

 

SSHの有効化は、以前はraspi-configのAdvanced Optionsにあったようだが、少なくとも今(2017/01/09)はInterfacing Optionsのようだ。


まずは、GPIOの割込みだけ確認しよう。
GPIO7が立ち下がったらコールバックされるというだけのしくみ。

https://github.com/hirokuma/rpi_rcs730/tree/08faec97ee7fea61dd3a5844ff28c48afbd755e1

WFIみたいなもので待たせたい気もするのだが、サンプルもぐるぐる回しているようなので、まあよしとしよう。

Drogon Projects | Git - wiringPi/blob - examples/isr.c

2017/01/07

[rpi]Raspberry PiでFeliCa Linkを動かす (1)

久々にRaspberry Piを動かそう。
ついでに、FeliCa Linkも動かすことにする。

 

基本的な配線は、これでよいだろう。
hiro99ma blog: [felica]FeliCa Linkを動かす

image

FeliCa Linkのピンは、写真のこの方向で上から順に1, 2, ..., 6番となっている。
RFDETはLEDに、IRQはGPIO4に、SDA/SCLはSDA0/SCL0に接続した。
LEDは、搬送波検知で点灯させたいだけだ。

LEDは抵抗を付けた方が良いのかもしれん。
付けよう。。。付けた。

 

この状態で、ソフトを書かなくても搬送波検知だけはできる。
うちのNexus5を近づけると、ちゃんと点灯した。


ソフトの方を作る前に、Raspberry Piの準備をせねばならぬ。

ここからRaspbianのJESSIE LITEをダウンロードして、うちはWindowsなのでWin32DisImagerをインストールし、SDカードにWriteするだけだ。
https://www.raspberrypi.org/downloads/raspbian/

SDカードをRaspberry Piに挿して・・・
HDMIのモニタが近くにないので、UART-USB変換ケーブルをピンに挿して起動する。
UARTは115200bpsだった。
loginが出てくるので、「pi」「raspberry」でログイン。

wifi設定は、こちらを見て、WPSした。
Raspberry Pi Raspbian Wheezy(2015-05-05)で最速Wi-Fiセットアップ - Qiita
うちのは、PlanexのGW-USNanoの古いやつだったと思う。

 

I2Cは、こちらを見て有効にした。
Raspberry Pi の I2C を有効化する方法 (2015年版) – ymyzk’s blog
raspi-configを使った。
2016/11/25版のraspbianだからかわからないが、メニューは7番だった。
それ以外は、同じ(再起動は求められなかった)。
が、だいたいそういうのは失敗しそうだから再起動した。

FeliCa Linkは、こう見えた。

pi@raspberrypi:~$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

FeliCa Linkのユーザーズマニュアル「5.2.5 I2Cスレーブアドレスレジスタ」によると、出荷時設定は0x40で、レジスタは7bit分だから、そのままI2Cアドレスとして使えばよいだろう。
いや、たまに1bitシフトして8bitのアドレスを示している(下位1bitはR/W)ことがあるので、ビット数を確認しないと不安なのだ。


そして、どうやってI2Cにアクセスするとよいのだろうか。。。

Raspberry Pi でI2C: C言語プログラミング - 猫ぱーんち!

open()して、ioctl(I2C_SLAVE)でスレーブアドレスを指定し、あとはread()/write()でアクセスできるようだ。
lsすると、/dev/i2c-1があるので、これでよいのだろう。
0からじゃないのですな。

 

昔書いた、mbed用FeliCa Linkライブラリを見てみる。
RCS730 - a mercurial repository | mbed

そうか、IRQの立ち下がりで処理を始めるから、割込み検知する必要がありそうだ。

Raspberry PiでGPIOを使った割り込み処理を行う - ORBIT SPACE

WiringPiでできるらしい。

 

これで材料は揃ったと思うので、あとは作っていくだけだ。
それは、次回以降で。

[android]paho mqttを使いたい (2)

前回はsubscribeだけだったので、今回はpublishまで行う。

変更後のgithub

publish自体は、簡単だった。
慣れないので、EditTextからどのタイミングでpublishさせたらよいのか悩んだり、TextViewのスクロールをどうやったらよいのかとか、そういうところに時間がかかった。

 

どうでもよいところだが、MQTT brokerをiot.eclipse.orgにしてみた。
家の中でmosquittoを立ち上げていたのだけど、ちょろっと動かすためにVirtualBox起動して、VM立ち上げて・・・というのが面倒だったのだ。
利用制限とかユーザ登録とかなさそうだけど、どこまで使ってよいのだろうか?
pahoはeclipseなのでそこまで悪いことはしてないと思うが、paho以外でも使えるだろうし。
ここは「さすがeclipse!」と褒め称えることにしておこう。

特に凝ったコーディングにはしていないつもり。
ただ、トピック名は「hirokuma@github」にしているので、この辺りを修正しておいたほうがよいだろう。
まあ、見られて困らないなら、そのまま使ってもらってもよいです。

2017/01/06

[android]paho mqttを使いたい (1)

以前、paho.mqttをpythonで使った。
あれは使いやすかったので、今度はそれをAndroidでも使いたい。

paho.android.service

githubにあるのだが、なんか使い方がpythonのときよりも面倒そうだ。
まあ、Androidのルールにあわせないといけないので仕方ないのだが。。。


今回は、こういう構成で試す。

  • 本体:Nexus5 + Android 6.0.1
  • Android Studio 2.2.3 (Windows 10 Home 64bit)
  • API 22(Android 5.1)

まず、Android StudioでEmptyな画面のプロジェクトを作った。

次はライブラリの追加なのだが、何だかよくわからない。。。
Android Studioの「File > Project Structure...」で、左からappを選び、タブの「Dependencies」をクリック。
右上のプラスアイコンをクリックし、1番のLibrary Dependencyを選択。
検索できるので「paho.client」と入力し、虫眼鏡をクリック。
いくつか候補が出てくるので「paho.client.mqttv3」を選択してOKする(testやrepositoryが付いていないやつ)。
同じようにして「paho.android.service」を追加する。

ただ、これだとgithubに書いてある最新バージョンが出てこなかった。
PropertiesタブのLibrary Repositoryにpaho-releasesのURLを書いて検索しても、出てこない(paho.android.service:1.0.2が出てくる)。

image

が、1.0.2を1.1.0に書き換えてOKすると、追加してくれた。
Library Repositoryに記載する前はできなかったので、そういうものなのだろう。
(mqttv3は1.1.0だったので、今だけの話かもしれん。)

image

この状態でビルドして実機に焼くと、警告がたくさん出るもののビルドは成功して動いた。
「Ignoring InnerClasses attribute for an anonymous inner class」などと出てくる。
ProGuard関連のようだが、今はアプリに何もやっていないし、無視しておこう。


あとは、サンプルをまねしていけばよいのか?

 

AndroidManifest.xml

<application>にserviceタグを追加するのはわかるが、<uses-permission>はこんなにいるのだろうか?
ACCESS_NETWORK_STATEとINTERNETはなんとなくいりそうな気がするが、他はアプリの内容次第ではなかろうか。
まあ、<uses-permission>は動かなかったら追加することにしよう。

 

PahoExampleActivity.java

これをまねして、adadHistory()みたいなものは、Log.d()で出力させることにした。
importできていないものは、Alt+Enterでお任せすると、動きそうなコードができた。
publishは面倒なので、まずはsubscribeだけ試そう。

 

これで起動すると、WAKE_LOCKが無いということでアプリが起動できなかった。
追加すると、次はACCESS_NETWORK_STATE。
その2つを追加するとエラーは出なくなったものの、MQTT brokerとの接続に失敗している。。。

なんとなくINTERNETも追加すると、今度は接続できた!
警告も出ずにうまく行かないのは、API 22でやっているからだろうか?

 

ともかく、subscribeまでしているので、ソースをgithubに上げておこう。
Brokerが192.168.0.70:1883になっているが、これはうちの中のVirtualBoxに立てているMosquittoだ。

github - android_paho_mqtt_test

 

次回は、publishするサンプルだ。
どうせボタンを押したら文字列を送信する、というだけになるだろうが、今日は力尽きたので次回にしよう。

 

そういえば、ProGuardの設定はうまくいかなかったら変更する、といっておきながら、変更したままになっていた。
コメントアウトしても動いているようなので、元に戻しておこう。
https://github.com/hirokuma/android_paho_mqtt_test/blob/master/app/proguard-rules.pro