2015/12/30

[esp8266]HTTP GETする

検索して出てきたESP8266のサンプルを見ながら、HTTP GETするサンプルソースを書いた。

https://github.com/hirokuma/esp8266_httpget

 

user_init()がメイン関数代わりというわけではないんだな。
別のサンプルがタスクを使うタイプだったから、WiFiのイベントとタイマや通信、GPIOなどの割込みでタスクで回していくような考え方でよいのかな。

また、UART0が自分が出したメッセージ以外にもいろいろ出しているのがわかった。
他の機器と通信するなら、system_uart_swap()とかos_install_putc1()を使うか、system_set_os_print()を使うかするのが良いのか。

 

しかし、こういうSSIDやパスワードのような自分の環境に関する情報をソースに埋め込むタイプは、githubとかに置くときやログを載せるのに苦心するな。


追記:

espconn_sent_callback()というAPIを呼んでみたが、これはたぶん間違いだ。
https://github.com/hirokuma/esp8266_httpget/blob/master/user/user_main.c#L135

PDFに、espconn_send()の注記としてこう書いてあったのだ。

Please call espconn_send after espconn_sent_callback of the pre-packet.

私はこれを「espconn_sent_callback()のあとでespconn_send()を呼んでくれ」と解釈した。
でも、espconn_sent_callbackは関数じゃなくて、typedefした型名のようだ。
使っているのは、espconn_regist_sentcb()。
recvcb()があるのにsentの方はAPI名が違うんだなー、などとのんびり考えていたのだけど、ちゃんとあったのだ。

いま、手元に環境が無いので確認できないけど、たぶんそうだろう。

2015/12/29

[esp8266]ICACHE_FLASH_ATTR?

SDKのサンプルを見ていると、ICACHE_FLASH_ATTRというマクロをしばしば使っている。
関数定義のところで使われている。
さて、なんだろうか?
名前からすると、FLASHの命令キャッシュに保存してよい、みたいな感じがするが。

気にしているのは、FLASHがSPIのところだ。
SPIってことは、シリアル。
データバスでアクセスするわけじゃないので、どこか一度RAM上に展開しないと実行できないのがノイマン型コンピュータの宿命だと思う。
メモリマップを見ると、iromはだいたい1MBまでになっているから、ESP8266の内蔵RAMが1MBあって、起動時に全部読込んでいるのでは?という予測をしていたのだ。

関数ごとにキャッシュに入れるとか入れないとかいう指定ができるなら、なんか関係していそうだ。


"ICACHE_FLASH_ATTR" macro - ESP8266 Developer Zone

FAQだった。

 

  • ICACHE_FLASH_ATTR付きの関数はコンパイル時にiromセクションに割り当てられる。
    CPUは必要なときにFLASHから関数コードを読み出す。
  • ICACHE_FLASH_ATTR無しの関数は起動時にiramセクションに読込まれる。

全部のコードをiramに置くことはできないので、FLASHに置いたままでも良い関数にはICACHE_FLASH_ATTRを付けてくれ。
でも、割り込みハンドラには付けるなよ。

 

とのこと。
CPUが自動的にFLASHから読み出すんだ。
読み出したコードは、実行したらすぐ捨てられるんだろうか?

リンカスクリプトを見ると、iramのサイズは0x8000だから、32KB。
割り込みハンドラや、あまり処理時間を掛けたくないところはそこに置くと良いのかな。

[esp8266]Non-OSのHello World

Linux環境でやることに決めたので、自分で書いてみよう。
前回とほぼ同じになるが、”Hello World”を115200bpsで出力するのだ。

https://github.com/hirokuma/esp8266_helloworld

 

最初は、user_init()を抜けていたのだけど、そうするとステーションモードになりそうなログを出していたので、while()で止めるようにした。

それだけだと寂しいので、system_deep_sleep()で眠っておいてもらおうとしたのだが、どうもWDTが作動して再起動してしまうようだ(再起動するときも115200bps設定のままになるためか、最初のログがちゃんと見える)。
なので、芸はないけれども、system_soft_wdt_feed()でWDTを起こすようにした。

Programming Guideを見ると、wdt_stop()もあったのだが、6秒以上止めるとHardware WDTでのリセットが作動するらしい。
じゃあ、API名がsoft_wdtと書いてあるけど、実際にはhardwareのWDTを触っているのか?
HDKのドキュメントを検索したけど、WDT関連を見つけられなかった。
うーん、気持ち悪いな。


ちなみに、起動時のログはこういうのを吐き出しているようだ。

 

ets Jan  8 2013,rst cause:1, boot mode:(3,5)

load 0x40100000, len 1396, room 16
tail 4
chksum 0x89
load 0x3ffe8000, len 776, room 4
tail 4
chksum 0xe8
load 0x3ffe8308, len 540, room 4
tail 8
chksum 0xc0
csum 0xc0

2nd boot version : 1.4(b1)
  SPI Speed      : 40MHz
  SPI Mode       : QIO
  SPI Flash Size & Map: 32Mbit(1024KB+1024KB)
jump to run user1 @ 1000

 

boot_v1.4はFLASHの先頭に焼いているのだが、これは2ndブートになるんだな。
ドキュメントには「プログラムできる内蔵ROMはない」とあるので、そこに1stブートがあるのだろう。
ということは、最初に出てくるログは止めようがないんだ。。。

image

[esp8266]Windowsでビルドするのはあきらめた

前の記事で、cygwin(+Arduino環境用GCC)でビルドしたuser1.binは実行できず、Linuxでビルドしたuser1.binは動いた、という結果に終わった。

それだけでは、考察が甘いだろう。
何がダメだったのかの理由まで調べておきたい。
ただ、本職じゃないので、ありがちなところだけチェックしておこう。


まずは、GCCのバージョンから見ていく。

  • Linux
    gcc version 4.8.2 (crosstool-NG 1.20.0)
  • cygwin+Arduino (xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2)
    gcc version 4.8.2 (GCC)
  • esp8266-gcc5.2.0-r5.exe
    gcc version 5.2.0 (GCC)

うーん、「まずは」と書いているが、実はここに期待していたのだ。
何かしらバージョンが違うことによって、どこかバイナリに食い違いが出たんじゃなかろうか、と。

当てが外れた。
ひとまず、5.2.0を評価するのはやめよう。


cygwinでビルドしたときのbinと、Linuxでビルドしたときのbinは、バイナリのくせにあまり違いがない。
なんとなくだが、数字の違いを見ていると、アラインメントに関係するような気がした。
04とか、10とか、そういう数字に違いが多いからだ。
違うかなぁ。

地道に生成しているファイルを比較したところ、オブジェクトファイルの段階で差があった。
readelfすると、Linuxではアラインメントが1なのに、cygwinでは4であつかっているところがある。
全部ではないのだが、ところどころ見られる。

やはりコンパイラをArduinoから間借りするというのがよくなかったか。


じゃあ、ちゃんとインストールした5.2.0だったらうまくいくかと思ったが、コンパイル中にあれこれ関数定義がないと言われる(ets_memcpyとか)。
インクルードが足りないのかと思ったが、インストールした5.2.0の中にもSDKがまるまる入っているなど、なんかいろいろ考えるところが発生しそうだ(そっちの環境も、それはそれでmake関係のエラーが出たり)。

 

うん、もう、めんどくさいからWindowsでビルドするのはあきらめよう。
ここでがんばる時間がもったいない。

2015/12/28

[esp8266]UARTを115200bpsにする

RTOS版を保留して、まずはnon-OS版でビルドすることにした。
以前、ATコマンドのサンプルはビルドして動かしたことがあるので、もう少しシンプルなものにしたい。

選んだのは、smart_config。
何をするのかはわからないけど、最初にos_printf()とあるから、文字列をシリアル出力するところが見えればいいだろう。

ビルドして、焼くが、なんかシリアル出力がゴミ。
そういえば、あまり普通じゃない速度がデフォルトだったよな、と思って検索すると、デフォルトは74880bpsなので、uart_init()で変更すればよいとのこと。

ふむふむとuart_init()を呼び出したのだが、リンクエラー。
UartBautRate(Baud、じゃないんだ)というenum定義っぽいので、includeを検索するが出てこない。
なんだこれは?

 

調べた結果、uart_init()はexamples/driver_libにいることがわかった。
気付かんわ。。。
中身を自分のプロジェクトにコピーして、Makefileを書き換えるのだ。
そしたら、ちゃんと115200bpsで出力された。

なお、デフォルトではUART0に出力するようになっていて、WROOM-02なのかスイッチサイエンスさんのボードがそうなのかはわからんが、ピンのRX/TXで出ているのはUART0なので、気にせず使えるようになっている。

 

たぶん、コンパイルオプションでwarningがあまり出ないようになっているので、-Wallくらいは追加したいな。
また、使っていない関数をリンクから外したいのだけど、大丈夫かな?

 

それよりも今回の大きな発見は、cygwinでビルドしたものを焼いてもうまく動かなかった、ということだった。
こっちを使った方がよいのかな? 次回試そう。
http://gnutoolchains.com/esp8266/

[esp8266]ESP8266_RTOS_SDKのexamplesをcygwinでビルド (4)

バージョンのことはひとまず置いて、ビルドのことに戻ろう。

W-ROOM02は、4MBのSPI-FLASHがつながっている。
SDKのUser Manualでは、4MB時のメモリマップが2つ用意されている。
FOTAありと、FOTAなしだ。

FOTAあり

image

 

FOTAなし

image

 

Irom0text.binは、正式名称「eagle.irom0text.bin」で、実行するコードが入ったものだろう。
Flash.binは、正式名称「eagle.flash.bin」で、なんだろう? 本番アプリを起動するためのスタートアップ処理みたいなものか。

ドキュメントの最後の方にアドレスが書いてある。
4MB時のも書いてあるのだが、FOTAありのアドレスは512KB+512KBのときのアドレスだろう。

FOTAありの方は、user2.binが0x8_1000になってるけど、これって512KBのとこだから、説明と合わないなあ。
たぶん、user2.binは0x10_0000からで、master_device_key.binは0xF_E000からになるんじゃなかろうか。
リンカスクリプトのeagle.app.v6.new_2048.ldだと、そんな感じに見える。

しかし、リンカスクリプトの方はシステムパラメータの領域が0x0F_0000と0x1F_B000からになっている(説明図が)。
ちょっと領域が広いし、配置は1MBの最後になっているから、esp_init_data_default.binのアドレスと合わない。
うーん・・・。
ドキュメントが間違っているのか、スクリプトが間違っているのか、RTOS版はそういうものなのか・・・。

 

うーん、RTOSを使わないといかんほど、複雑なことをしなければよいんじゃないか?とすれ思い始めてしまった。
いや、そういう後ろ向きの考えじゃいかんな。
まずは、素のSDKで作ってみるべきじゃなかろうか?
うんうん、それがいいそれがいい!

[esp8266]ESP8266_RTOS_SDKのexamplesをcygwinでビルド (3)

あやふやな情報で進めてしまったのを反省し、ドキュメントをちゃんと読もうと思う。

 

最新のSDKは、こちら。
[Latest Release] ESP8266 SDK - ESP8266 Developer Zone

ドキュメント一覧は、こちら。
Complete Listing of Documentation Released (文档目录清单) - ESP8266 Developer Zone

SDKのドキュメントは、こちら。
[Document list 2A-2C] ESP8266 SDK Development Guide - ESP8266 Developer Zone

RTOS SDK版のプログラミングガイドは、こちら。
RTOS SDK Programming Guide - ESP8266 Developer Zone

SDKにはnon-OS版とRTOS版があるのだが、ドキュメントの階層を見るとこうなっているようだ。

  • ESP8266 IOT SDK (User Manual, Programming Guide)
    • non-OS SDK (Programming Guide, SSL User Manual)
    • RTOS SDK (Programming Guide, API Reference)

 

記事を書いている時点でのSDKはこういうバージョン。

image

うーん、このバージョンをどう見たらよいのか。。。
non-OSのv1.4.0が2015年9月18日、RTOSのv1.2は見当たらなくてv1.1が2015年8月21日。
普通に考えると、non-OS版を作ってそこにRTOSを移植するだろうなぁ。
RTOS v1.3.0のリリースを見ると、APIをnon-OS SDKから同期した、と書いてあるから、やはりそうなのか。
non-OS v1.5.0で追加されたespconn_abort()なんかはドキュメントに入ってないし、v1.4.0で追加されたsystem_show_malloc()も入っていない。
かといって、v1.3.0で追加されたsystem_soft_wdt_feed()は入ってないが、wifi_softap_get_dhcps_lease()は入ってるな・・・。
あ、v1.4.0追加のwifi_softap_set_dhcps_lease_time()は入ってる。
RTOSのwikiには、non-OSとAPIは一緒だ、と書かれている。

日付の順に出しているだけだったら、じゃあRTOSのv1.2.0がないのはなんでだ?
わからない、わからない・・・。

[esp8266]ESP8266_RTOS_SDKのexamplesをcygwinでビルド (2)

さっそくで申し訳ないが、前の記事の訂正だ。
訂正というか、私の認識違いだったのだけど、最後のログ出力を見て気付いた。

Generate user1.4096.new.6.bin successully in BIN_PATH

BIN_PATHは、GCCの実行ファイルが入ったパスじゃ無くて、インストール先のパスに近いもののようだ。
configureでいうところの、—prefixみたいなもの。
なので、こういう感じにした方がよさそうだ。

export SDK_PATH="e:/Prog/esp8622/ESP8266_RTOS_SDK"
export BIN_PATH=`pwd`/bin
export XTENSA_GCC_PATH="/cygdrive/c/Users/xxx/AppData/Local/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/bin"
export PATH=$XTENSA_GCC_PATH:$PATH
mkdir -p $BIN_PATH


前に調べた、アドレスを見ておこう。

image

image

 

不自然だ。
USER1とUSER2が同じソースでやるのだったら、User paramの16KBとSystem paramの16KBは同じ位置にいないといけない気がするのだ。
いけないというか、別にこういう持たせ方をしたくても悪くは無いのだけど、どこでそれを決めているのだろうか?
だって、4MBのFLASHがあって2分割するなら、2MB+2MBにするのが自然だと思うのだ。
でも、これは1MB+1MB+自由領域、みたいな割り方になっている。

USER2の領域にはUser paramの領域が無い。
これはSystem paramの領域でまかなうのだろうか?
そういうことを考えながらアプリを作ると、USER1と2のどっちで起動したかなど気にしたくないので、自由領域をUSER1/2で共通に使うようにするだろう。

そして今さら気づいたのだが、FOTA有り時と無し時でflash.binの位置が違う。
FOTA無し時はSPI-FLASHの先頭にあるのだ。
FOTA有り時には、先頭がBootになっている。
前回も、FLASHに焼くツールで最初に指定しているのはboot_v1.4(b1).binだ。

 

うん、まだまだ考え方が甘いな。
今日はここまで。

2015/12/27

[esp8266]ESP8266_RTOS_SDKのexamplesをcygwinでビルド (1)

はあ、またBLEとESP8266が混在してしまった。。。

ESP8266をArduino上でビルドしたり焼いたりする環境を作ったが、RTOSもいいよ、という記事を読んだ。
Espressifが出した環境で使えるようにしておいた方が無難か、という気持ちもあり、とりあえずサンプルソースだけでもビルドしてみようとした。

うちは、Windows7 64bit + cygwin 32bitだ。


githubのespressif/ESP8266_RTOS_SDKからcloneする。
ここのREADMEにWindowsでビルドできるような感じで書かれていたのでコマンドプロンプトでやっていたのだが、Makefileでincludeするときにパスをどう書くのかわからなくなってきたので、cygwinでやることにしたのだ。

環境変数のSDK_PATHとBIN_PATHを指定する。
これは、gen_misc.shの中にある。
あるのだけど、ビルドの最後の方でpythonを呼び出し、そこからESP8266用のNMコマンドを呼び出そうとしている。
xtensa-lx106-elf-nmを呼び出すのだが、パス無しで書いてあるのでPATHに書いておくくらいしかやり方がわからんかった。

そしてまた、Windowsで動くESP8266用のGCCをインストールせんといかんのだが、Arduino環境を作るときにインストールしてくれているようなので、それを使うことにした。

cygwinでパスを書くとき、ドライブを指定する「c:/」みたいな書き方もできるし「/cygdrive/c/」みたいな書き方もできる。
でも、PATHに追加すると区切りが「:」なので、前者の形式で書いておくと都合が悪い。
しかしそちらに合わせておくと、gccがインクルードパスの解決をうまくやってくれなかった。

そういう、もろもろの事情があって、gen_misc.shの最初はこういう感じになった。

export SDK_PATH="e:/Prog/esp8622/ESP8266_RTOS_SDK"
export BIN_PATH="/cygdrive/c/Users/xxx/AppData/Local/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/bin"
export PATH=$BIN_PATH:$PATH

ここでPATHをやってるけど、結局これをコンソールで実行しているので、実は意味が無いかも。
ただ、ここに書いておくと、これをコピーして、コンソールにぺたっと貼り付ければ済むので、ついでに書いているのだ。

 

makeも、引数がいろいろ付けるのだが、毎回打ち込むのもめんどくさい。
なので、$inputがY以外のときに、こういう行を追加した。

make BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=6

APPの指定は、実はどれがいいかよくわかってない。
前回調べたとき、FOTAで更新するときにはUSER1とUSER2をそれぞれ作るイメージだったので、まずはUSER1を作ろうとしている。
SIZE_MAPが6なのは、うちにあるESP8266モジュールのSPI-FLASHが4MBだからだ。

 

これでコンパイルが進むのだが、リンクで怒られた。
libhal.aがない、ということだ。
よくわからないが、検索するとesp8266-Arduinoのgithubにバイナリがあったので、何も考えずにダウンロードしてlibに置いた。

 

解決しても、次もリンクエラーだ。
.irom0.textがフィットしないとか、そんなエラー。
検索すると、リンカスクリプトの変更がいるみたいだ。
デフォルトでは$(SDK_PATH)/ld/eagle.app.v6.ldを使うのだけど、これはSPI-FLASHが512KB用の設定になっているみたい。
なので、これを4096KB用の設定にすればいいのだが、サンプルでは2048KB用までしかない。

とはいえ、前回IOT_SDK_User_Manual v1.4でも4096KBは(1024KB+1024KB)という扱いだった。
前半にUSER1とUSER2を詰めて、残りはシステムパラメータ以外なら好きに使ってよいというスタンス。
なので、eagle.app.v6.new.2048.ldをコピーして、eagle.app.v6.ldにリネームしておく。

 

それで進むようになったのだが、今度はpythonスクリプトで「no entry point!!」とか言われる。
スクリプトを読むと、eagle.app.symの中からcall_user_startを探しているようだ。
ないのかと思ったが、テキストエディタで開くと見つかる。
ということは、この正規表現がcygwinだとうまく動かんということか。。

p = re.compile('(\w*)(\sT\s)(call_user_start)$')

行末が「call_user_start」になっているところを探しているのだが、cygwinでコンパイルしているためSYMファイルがCR/LFで改行しているため、これにひっかからないみたい。

p = re.compile('(\w*)(\sT\s)(call_user_start).*$')

これだったら、call_user_startの後ろに1文字あってもなくてもよいのかな?
でも、call_user_start1にもヒットしてしまいそうだ。

p = re.compile('(\w*)(\sT\s)(call_user_start)(\r*)$')

こんなのの方が良いのかも。

 

ここまでやると、こういう出力が出て、終わった。

bin crc: 70347e4
Support boot_v1.4 and +
Generate user1.4096.new.6.bin successully in BIN_PATH
boot.bin------------>0x00000
user1.4096.new.6.bin--->0x01000
!!!

 

今回ビルドしたサンプルはwebsocket_demoという名前なのだが、はて、いったい何が動くのだろうね?
続きは次回だ!

[nrf51]PairingとBonding (2)

hiro99ma blog: [nrf51]PairingとBonding

そういえば、Bondingに対する私の理解が解決していなかったことを思い出した。
まあ、ありていにいえば「よくわかってない」なのだ。


Bonding without passkey is possible using nRF51822? - Nordic Developer Zone

パスキー無しでBondingできますか?という質問。
「Yes」、彼は軽やかに答える。

パスキー無しということは、お互いで同じパスキーを固定で持っているのと同じ、ということのようだ。
MITMビットを0に、IO capabilitiesをBLE_GAP_IO_CAPS_NONEにすると、Just Worksというペアリング動作になる。

In that senario、で、お互いパスキーが”000000”を使う、と書いてあるが、シーケンスにはパスキーの中身は出てこないので”000000”という値も固定なのかな?
質問者も同じことが気になったようだが、回答としては「S110は自動的に000000を使うが、電話メーカーによっては0のみのパスキーをエラー扱いにするところもあるので注意してね」ということらしい。

回答者は、BLEのセキュリティは”not very secure when using PIN authentication”という認識を持たれているようだ。
OOB > PIN > Just Worksの順にsecureで、Just Worksは全然secureじゃないよ、と。


という予備知識を身につけたところで、仕様書を確認しよう。
Vol.3 Part.H “Security Manager Specification”だ。

まず、このシーケンス図。

image

PDFのp.2285(Core_V4.2)に乗っているのだが、フェーズが3つある。
これが、NordicのBondingシーケンスに出てくるフェーズか。
なんの数字かわからないままだったのだ。

フェーズは、こういう名前が付いている。

  • Phase1 : Pairing Feature Exchange
  • Phase2 : (LE legacy pairing)  Short Term Key Generation
  • Phase2 : (LE Secure Connections)  Long Term Key Generation
  • Phase3 : Transport Specific Key Distribution

Phase2が2つある。
どちらもLEがついているのだけど、Part.H自体は表紙に”LE-only or BR/EDR/LE devices”とあるから、LE専用の章ではないのだと思う。
上の図だって「LE Paring Phases」なんだけど、それ以外のシーケンス図が見当たらない。
どこか読み飛ばしているのだろうか。。。

 

Connectionシーケンスの一部では無く、Connectionの後に行うシーケンスなのだ。
まあ、失敗したら切断するのだろうけども。

まず、フェーズ2で次のどれを使うか決めるために情報交換する。

  • Just Works
  • Numeric Comparison
  • Passkey Entry
  • Out Of Band

Numeric Comparison?初めて聞いた。
これはBLE専用らしい。
Core_V4.1のPDFには載っていないから、4.2から新しく追加されたのだ。

暗号化の細かいところは読み飛ばすが、AES-128bitのようだ。
128bitということは、16バイト。
データのどこから暗号化するのかはまだ読んでいないが、元が16バイト以内のデータなら16バイトに、32バイト以内のデータなら32バイトになるのだろう。
ブロック暗号だから、そうなるはず。。。自信はないけど。。。


パケットのフォーマットは、Vol.6 Part Bにあった。

image

一番短いパケットは80bit、一番長いパケットは2120bitとのこと。
そうだ、Core_V4.2からPDU長が拡大されたんだ。

BLEスニファでこういう風に見えているデータがあったとして、

image

これのうち、実際に無線として出回っているのはここまでということだ。

image

プリアンブルは、Advertisingのチャネル(37~39)で流す時とそれ以外でルールが違うようだ。
面白そうではあるが、そういうのは下回りを作る機会があったときために残しておこう。

 

このうちのどこが暗号化されるか。
アクセスアドレスの説明を読むと、ペアリングしたときの情報で生成する方法もあるようだから、AESで暗号化するのはせめてPDU以降ということか。
CRCはPDUの部分を計算するようだから、CRCも暗号化対象外だろう。
つまり、無線を受信したら、暗号化を解読せずにデータが正しいかどうか判断できるというわけだ。


長くなってきたので、今回はここまで。

[ble]Prepare Writeしか来なかった

こんなことがありました、という報告。

 

BLE Peripheralの動作確認をしようと、スマホアプリから操作をしていた。
前日にお客さんのところで動作確認したスマホアプリで、Peripheralアプリは更新したものだ。
Advertisingはしてるし、Connectも張れるのだけど、なぜかCharacteristicへの書き込みがうまく行かない。

まずはデバッガで追ってみたところ、nRF51822でAuthorized Write設定していたのに、コールバックではただのWriteとしてやってきていたのだ。
そのため、Replyを返す関数を呼んだときに「そんな状態じゃ無い」というエラーが起きていた。
どこかで設定を間違えたかと思ったが、そこら辺は修正していない。
Characteristicの設定直前に値が書き換えられたのかとも思ったが、そうでもない。
うーむ。

いろいろ見てもわからないので、BLEスニファで流れを見てみることにした。
そうすると、スマホからWriteじゃなくてPrepare Write Requestが飛んできていた。
1バイトのデータなのに!
それならば、このシーケンスになるのは仕方が無い。

 

じゃあスマホアプリが問題かと思ったのだけど、どうもそういうところが見当たらない。
よくわからないので、nRF Master Controlアプリから書込んでみたが、これもだ!
いつも普通に書き込みをしていた彼ですらPrepare Write Requestしてくるのだ。

これはもうおかしいだろうとスマホを再起動すると、直った。


BluetoothのOFF/ONだけで直ったかもしれないので、そこは失敗したな。
しかし、現象としてこういうのが起きてしまうと、ちょっと悩んでしまう。

1byteのデータをLong Writesしてくるというのは、まっとうではないと思うけれども、プロトコルとして間違っているわけでもないと思う。
なので、Centralのスタックが「めんどくさいから常にLong Writesする」みたいな作りになっているものが出てこないとも限らない。
まあ、Long Writesに対応しているPeripheralの方が少ないとは思うのだが、可能性としては、だ。
・・・そこは相手を信用してもよいのかな。
Centralの気持ちがまだわかっていないから、やはりS130で実際にやってみよう。

でも、今回のはAndroidかNexus5のバグだと思う。

2015/12/26

今年の復習

少し早いが、今年の反省をしておこう。
反省と言っても、書いてきた記事についての反省だ。


記事の数

今のところ、2015年に投稿した記事は、314件だ。

image

わかりやすいのは、客先常駐の仕事を辞めた月の記事が異様に多いことだ。
まあ、10月は半分常駐、半分お休みだったので、収入も半分なんだけどね。
半分で25万いかないって、個人事業主の技術者として考えた方が良かったか・・・。
おっと、今はベースを上げているので、心配しないでおくれ。


NFC

うちのサイトと言えば、NFCのようだ。
Googleの検索候補だと、こう出てくる。

image

なんだよ、githubって。
ともかく、NFCのことを調べていた成果のおかげで、こういう候補になったようだ。

でもまあ、これはタイミングがよかったからだと思う。
このサイトは2011年の2月から始めているが、NFCのことを調べ始めたのは2010年だ(もう、そのサイトは無い)。
当時はNFCのことなんか調べている人があまりおらず、その後でNFC Forumなるものが立ち上がったので調べる人が増えた、というところだろう。

今年はあまりNFCのことをやっていないが、FeliCa Linkを動かしたり、PC/SCの調査をやったりはしている。
技術としては好きなのだけど、iOS端末ではNFCのR/W機能が公開されていないので、公開されてからでいいや、と思われているのかもしれん。


BLE

今年はBLEの記事が多かったように思う。
まだPeripheralしかやっていないので、Centralもやってみらんといかんだろうと思いつつ、箸が止まった状態だ。

Bluetooth Developer Studioが出てから、あまりCharacteristicの実装について考えなくてよくなったので、次はIPv6とかかな。


WiFi

NFC、BLEと来たら、次はWiFiか。
ESP-WROOM-02という、ESP8266EXが載ったモジュールが安かったので買っているが、これでどこまで遊べるのだろうか?

WiFiやるのだったら、せっかくだからサーバの方も少しは触れるようになっておきたい。
自宅のサーバとかじゃなくて、たとえばAWSとかだ。
流行り物というには出遅れすぎなのだが、まったく知らないまま通り過ぎるのは寂しいだろう。

Arduino環境で使えるようにはしたけど、espressifのSDKとかとの関係がよくわかってない。
あまり難しいことができないのであれば、ATコマンドでGET/PUTだけした結果だけもらって別モジュールで処理するようにした方がよいだろうし。


まあ、来年もぼちぼちやりましょうかね。

2015/12/24

[esp8266]Arduinoに仕立てる

ESP8266は、Arduinoでコンパイルできるように仕立てることができるということなので、やった。

image

THE空中配線。

 

続・モノのインターネットのこれから ~カジュアルにモノのインターネットを楽しむ、その先の未来 (2/4):CodeZine(コードジン)

ほぼ、このまんま。
動かすサンプルが、mqtt_esp8266はコンパイルが通らなかったので、HTTP Getするだけのサンプルにした。
プロトタイプ宣言が無いのはまだよいとして、callbackってのがどこからどうするものかを調べるのがめんどくさかった。

ありがちだと思うが、うちはWiFiルータでMACアドレスをしばっているので、そこに追加し忘れて進まなくなっていた。
とりあえず、楽ですわ。
Windowsから全部できるし、サンプルが多いのでまねすればある程度のことはできそうだし。

でも、HTTP GetのサンプルだけでFLASHが60%、RAMが50%使っているらしい。
WROOM-02としては、FLASH(SPI)が4MByte、内蔵RAMは80KBあるみたいだ(Arduinoのコンパイルログだと)。
ただ、ESP8266のドキュメントにも、WROOM-02のドキュメントにも、ばしっとRAMのサイズが書かれていないようだ。
「今のSDKだと、36KBくらいユーザが使えるかな?」程度だ。
なので、この空きサイズがぜーんぶ使ってよいサイズだったらすごいのだが、まあやってればどこかでわかるだろう。

 

あとは、Arduinoでずっと遊んでいくか、SDKでやっていくかだけど、まずはArduino環境で慣れていきますかね。

[nrf]DFUライブラリはboards.hを見てる

愚痴だ。

DFUのサンプルを動かしているとき、Advertising中のLEDが点灯しなかった。
ソースを追っていくと、components/libraries/bootloader_dfu/dfu_transport_ble.cの中で、nrf_gpio_pin_clear()やnrf_gpio_pin_set()を使って制御しているようだった。
これが、アクティブLOWで決め打ちしているので、こんなHIGHで点灯するLEDの設定にしていると、点灯しないのだ。
ライブラリなのに、examples/bspにあるBSP_LED_0とBSP_LED_1を見に行ってるし。

やっぱり、components以下にあるものは、標準ライブラリかcomponents以下しか見ててほしくないのだな。
examplesなんてところを参照するのは避けてほしかった。
動きを変えたかったら、components以下を編集しないといけなくなるからだ。
SDK v11も、このままだったら同じになりそう。

 

しかし、どうしたものか。。。
bootloader_dfu以下をまるまるコピーして差し替えるしかないか。

ただ、私がLEDにVDDを結線し忘れてたから点灯すらしなかったというのは、あやまっておこう。
すまん。。。

[nrf51]DFU example

nRF5 SDK v11が出そうなところだが、出てしまう前にS110でDFUを試しておこう。
nRF Master Controlアプリがちょうど更新されたところなので、少し変わったところがあるかも。

 

SDK v10のドキュメントは、DFUの説明が多少古い。
ソースを正として扱おう。
また、DFUサンプルは32KBのRAM用にできているので、メモリマップなんかは適当に変更する。
ブートローダモードで起動したいなら、LEDはいいとしても、ボタンは用意しておくとよいだろう。
アプリが無ければブートローダモードで起動するらしいのだが、なんかうまくいかんかったのだ。

 

nrfjprog.exeで焼くように書かれているのだが、引数が変わっている。
書き込めなかったら、nRFgo Studioで消してからやろう。

image

 

焼くと、こんな配置に見えている。

image

 

スマホアプリは、こんな感じ。
ZIPファイルはGoogleドライブとかに置いておいても開ける。

imageimageimage

ZIPファイルの作成は、nrfutil.exeを使う。
Pythonファイルをexe変換しただけのような感じもするが、よくわからんのでそのまま使っている。

[nfc]PC/SCを試す (5)

では、ATRで返ってきたデータの中身を見ておこう。

IC運転免許証の場合
image

 

ATRは、仕様書Part3の3.1.3.2.3に記載がある。
分類は2つ。

  • Contactless Smart Cards
  • Contactless Storage Cards

NFCはメモリを持ってるからStorage Cardsの方かと思ったのだが、Smart Cardsの方に14443の記載があった。

  • [0]0x3B固定
    • Initial Header
  • [1]0x8n
    • T0
    • nは、ヒストリカルバイト(Historical bytes)の大きさ
    • 8も意味はあるのだけど、書いてある意味がわからないので省略
  • [2]0x80固定
    • TD1
  • [3]0x01固定
    • TD2
  • [4-7]Application Data from ATQB
    • 00 00 00 00
  • [8-10]Protocol Info Byte from ATQB
    • B3 81 C1
  • [11]
    • 上位8bit:MBLI from ATTRIBコマンド
      • 0
    • 下位8bit:RFU(将来のために確保)
      • 0

ということだ。

NFC ForumのDigital Protocol “5.6.2 SENSB_RES Response”では、ATQBはこうなっていた。

  • Application Data
    • 4バイト
      • AFI
        • 0x00
      • CRC_B(AID)
        • 0x00 0x00
      • Number of applications
        • 0x00
  • Protocol Info
    • 3バイト
      • Bit_Rate_Capability
        • 0xB3
        • only the same bit rate divisor for both directions is supported
        • D_POLL->LISTEN=4
        • D_POLL->LISTEN=2
      • FSCI
        • 0x8
        • FSC(maximum Frame Size)=256バイト
      • Protocol_Type
        • 0x1
        • NFC Forum Device in Listen Mode compliant with [ISO/IEC_14443]
      • FWI
        • 0xC
        • Frame Waiting Time Integer
      • ADC
        • 0b00
        • Application Data Coding
          • Advanced protocol features not supported
          • Application is proprietary
      • FO
        • 0b00
        • Frame Options
          • NAD not supported
          • DID not supported (DIDとCIDは同じもの?)
  • MBLI
    • 0
    • Maximum Buffer Length Index


IC免許証の仕様書を見ても、ATTRIBコマンドの形式や応答は0バイトらしいから、これでいいのかな。
とりあえず、ATRを見ただけでは、個人情報に当たるものどころか、これが運転免許証かどうかすらわからんということがわかった。

2015/12/23

[nfc]PC/SCを試す (4)

めんどくさくなったので、githubにプロジェクトを置いた。
https://github.com/hirokuma/PcscSample01

うちは、PaSoRi RC-S380/Sをインストールした環境だが、他のR/Wでもドライバを入れたりすれば同じように動くのでは無かろうか。
ACRさんのR/Wも気になるのだけど、PaSoRi以外って高いのよね。
ぷらっとオンラインさんが安そうだけど、まあ、物を増やすのはやめておこう。


今回は「Get Data」というコマンドを使ってみた。
初のカードへの送信だ(たぶん)。

https://github.com/hirokuma/PcscSample01/blob/master/PcscSample01/PcscSample01.cs#L150

どこからこの値が出てきたかというと、PC/SC仕様書のPart 3[pdf]からだ。
”3.2.2.1.3 Get Data Command”
HTML版もあるのだけど、そっちにはコマンドが載ってないみたいだし、”3.2.2.1.3”の目次がGet UID Commandになってるな。
最初なので、PDFから抜粋しておこう。

image

ときどき仕様書PDFの画像を載せてるけど、たぶんよくないよね。。。
取得先を載せてるし、承認がいるPDFの場合は載せてないつもりだから、許してほしい。

 

理屈はすっ飛ばして、このコマンドを流してみると、UIDが返ってきた。
これは、IC運転免許証も、nimocaもだ。
ただ、IC運転免許証はType-Bなので、PUPI、すなわち一時的なIDが返ってくる。
どのくらい一時的かというと、カードをコネクトしている間だけ同じになっているようだ。

FeliCaの場合にはIDmが取って来れたけど、これはデフォルトシステムのIDmみたいだ。
システムコードを指定して取ってきたいときは、たぶん生のコマンドをR/Wに流さないといかんのじゃなかろうかね。

ちなみにPaSoRiというかNFCポートというかでは、独自定義もあり、P1に0x00と0x01以外も指定できる。
この辺は、SonyのICS-D010/20Jにあるドキュメントを読まんといかんのじゃないかな。
まあ、私の今回の目標はType-Bを読むことだから、そこら辺には深入りしない。

 

これで、ようやくスタートラインくらいには立てたのかな?
まだAPIの使い方は甘いと思う。
pcsc-sharpのサンプルでは、CommandApduクラスやResponseApduクラスを使っていて、私のソースみたいにSW1やSW2を自分で分解しなくてもよくなっている。
https://github.com/danm-de/pcsc-sharp/blob/master/Examples/Transmit/Program.cs#L36
とはいえ、バイナリは自分で処理した方が面白いと思うから、これはこれでいいや。

2015/12/22

[nrf]GPREGRETレジスタ

nRF51822のリファレンスマニュアルを読んでいて、GPREGRETというレジスタがあることを知った。

何の略かはうまく表現できないが、General Purpose REGister for RETain、といったところか。
ブロックの位置は、POWER。
となると、あれだ、電源がある間は保持してくれるメモリだろう。
RTCの余ったレジスタや、WDTの再起動原因のレジスタに似たようなものだろうと思う。
(今知ったけど、nRF51822のRTCって、年月日みたいなのは持ってないんだな。)

 

最近のマイコンは、NVもRAMもいっぱいあるし、速度も機能もたくさんあるので、調子に乗って大味なプログラムを書いてしまいがちになっていた。
まあ、そっちの方がいいときもあるのだけど、たまには足下を見らんといかんですな。

[nrf]nRF5 SDK v11.0.0-2 alpha

nRF5 SDK v11.0 alpha now available

ばーん!という効果音があってもいいくらい、大きいリリースだと思っている(まだα版だけど)。
nRF51822でS130v2を動かしたときに、SDK v10ではコンパイルが通らなかったからそのうちリリースされるだろうとは思っていたのだが、年内とは思わんかった。

正式版になるときは、nRF52のSoftDeviceのメジャーバージョンが付いたときか、nRF51 S130のメジャーバージョンが正式に上がったときかじゃなかろうかね。

詳細はリリースノート参照のこと。
私が気になったところだけ、ピックアップしてみる。


nRF51とnRF52の統合

まずは、これだ。
”Common SDK”と書いているし、そもそも機能が違うから全部は統合できないのだけど、BLEのCentral/Peripheralとして動くだけだったら、同じように使えるのかな?
せめて、S130とS132、S210とS212は同じソースだとうれしいな。

 

S110がサポート外

そして、これだろう。
nRF52にS110相当のものが無いからか、S110が対象SoftDeviceに入っていない。
残念な気もするが、今までSoftDevice/SDKの変更によってソースの修正がたびたび発生していたことを思えば、肩の荷が下ろせるかもしれない。

「Permanently removed support」って書かれると、寂しいものがあるがね。

 

softdevice_handlerのマクロとsd_enable()のラッパ

いきなり地味なものを選んでしまった。
S130を試したとき、sd_ble_enable()で与えるRAMのサイズが計算できないままだったのだ。
これでサイズが合わないと、実際にAPIを使うときになって、例えばAdvertisingの開始時に「メモリが足りん」というエラーが起きるのだ。

softdevice_enable_get_default_config()CHECK_RAM_START_ADDR()かな?
BLE周りはAPIが追加だか変更だかになっているので、これを機にサンプルを見直した方がよさそうだ。

見直すと言えば、Bluetooth Developer StudioはまだnRF52向けは出ていないようだ。
まあ、S130でも動きそうなので、そこまで神経質にならなくてもよいのかな。

 

NFC関係

NFC関係が多い。
re-implementedということで、作り直したところも多いのだが、Type 2 Tagのパーサが追加されたり、NDEFメッセージビルダーなるものが追加されたりしている。
OOBのレコードを作るのも、簡単になるみたいだ。

それよりも気になったのが、Adafruit PN532シールドの移植だ。
PN532はUARTとかもサポートしてるのだけど、シールドとしてはI2CかSPIのようだ。
Arduinoのシールドだから、nRF51 DKやnRF52 DKにそのまま載せて使えるようにしたのかな?
でも、なぜ??
こういうのがまた流行るのなら、SonyさんにRC-S620/Sが載ったシールドとか出してほしいな。

技適のことを調べているときに、nRF51 DKやnRF52 DKも探してみたのだが、見つけられなかった。
となると、Arduinoのシールドが載せられるようなnRF51のボードは国内では売ってないんじゃなかろうか。
あるのかなぁ。。。
うちにはRC-S620/Sがあるから、ということで持ってないのだけど、やはりPN532は気になる。

PN532のシールドを載せて考えられるのは、nRF5がCentralになる場合だろう。
相手をBondingするとき、NFCペアリングなのであれば、自分がNFC R/Wにならんといかん。
うん、そういうことなんだろう。

2015/12/21

[nfc]PC/SCを試す (3)

鉄は熱いうちに打て、ということで、サンプルソースの中身を見ていく。

最初に書いておくが、本家のExamplesでは、各所でusingを使っている(★)。
usingから抜けると、Disposeを呼ぶようだ(こちらなど)。

  1. リソースマネージャーとの接続
  2. カードリーダー名の取得
  3. カードリーダーとの接続
  4. カードの状態取得

これだけだ。

1番目、2番目は、こちら。
スマートカードサブシステム

3番目、4番目は、こちら。
スマートカードへの接続

ソースに現れていないReleaseとかDisconnectとかは、Dispose時にうまくやってくれるのだろう。
だから、usingしておかないといかんのかな。

2015/12/20

[nfc]PC/SCを試す (2)

この「PC/SCを試す」シリーズは、PC/SCを試しつつ、Type-Bのことを調べ、HCEへの応用も効くんじゃないかと考えているという、欲深い企画だ。
うまくいくだろうか・・・。

昔の記事があったので、リンクを載せておこう。
hiro99ma blog: PC/SC
2年半も前なのだが、適当に調べただけのようだ。


PC/SCは、なんとなくWindowsで動くというイメージしか持っていないが、そもそもどういうものか?
II.2.2.3 PCでのカード利用
こちらによると、「PC上でのスマートカードを利用するための標準」とのこと。
対象はスマートカードで、PC上で利用するのが目的だから、無線の規格とかそういうのではない。
なので、最後はアプリケーションを作るときのAPIに落とし込まれるのだろう。

PC/SCの仕様書は公開されていて、現在は2.01.14だ。

image

こちらが、Part1に載っていたアーキテクチャーの図。

image

  • ICC
    • Integrated Circuit Card
    • 通称、スマートカード
  • IFD
    • Interface Device
    • 通称、スマートカードリーダー
  • ICC Resource Manager
    • PC/SCの鍵となるコンポーネント
    • ICCに関連したリソースを管理する責任を持つ
  • SPE
    • Secure PIN Entry
  • ICC Aware Application
    • 通称、アプリケーション

うーん、ピンとこない。
Interface誌2012年4月号を読むと、「アプリはリソースマネージャーからATRを受けとる」とあるので、アプリを作る人としてはリソースマネージャーと会話することだけ考えればよいのか。

ATRは、Answer-to-Resetの略。
似た用語が並んでいたので、並べておこう。

  • ATR
    • Answer-to-Reset
    • RESETコンディションになったときの応答として、ICCによってリーダへ送られる
  • ATS
    • Answer to Select
    • SELECTコンディションになったときの応答として、Type-AのPICCによってPCDへ送られる
      • PICCはProximity IC Cardで、PCDはProximity Coupling Device。NFCで出てくる言葉。
  • ATQA
    • Answer to Request for PICC type A
    • REQAコマンドに対して、Type-AのPICCによってPCDに戻される
  • ATQB
    • Answer to Request
    • REQUESTコンディションになったとき、Type-BのPICCによってPCDへ送られる

この訳し方で合ってるのか?
ATRは接触型のカードで、それ以外は非接触型のカードを指しているように見える。


PC/SCをやりたいとなると、このページだろう。
スマートカード - EternalWindows

次回は、このサイトを参考にして、前回のCardStatusサンプルが何をしているのか読み解いていこう。
最初は模倣から始まるのだ(えらそう)。

Visual Studio Team Servicesという名前になっていた

PC/SCのサンプルを作るとき、githubに置こうかと思った。
が、こういうときでもないとVisual Studio Onlineを使わないよなあ、と思ってログインした。

image

名前が、Visual Studio Team Servicesになっていた。
いつの間に!


これだけだとあんまりなので、先にVisual Studioでソリューションを作った後で、VSTSの管理下に置く方法を調べよう。
Gitじゃなくて、Team Foundation Version Controlの場合。
プロジェクトを作るときにはソース管理する気持ちがなかったけど、やっぱりやろうと思った、というときだ。

 

image

まずチームエクスプローラーを開いたのだが、さっきのPcscSample01が残ったままになっている。
「新規作成」を選んでも、新しいプロジェクトを作る動きになるし、「開く」としても単にプロジェクトを開くだけだし。

と思ったら、メニューに「ソース管理に追加」というのがあった。
これだったのか・・・。

image

image

image

ただ、この次のダイアログで、行き詰まった。

image

チームプロジェクト、というのがリポジトリみたいな位置づけなのだと思うが、これを作ることができない。
いったん、ここは引いて、ブラウザで操作しよう。

 

image

この「New」をクリック。

image

PcscSample02というプロジェクトを作ろうかと思ったけど、さっきのメニューからすると、1つプロジェクトを作っておき、その下に似たようなソリューションをぶら下げていくのがよいのかな?と思った。
なので「PCSC」という名前にしておこう。

image

そして、もう一度Visual Studioでソース管理に追加。

image

うーん。
チームプロジェクトの場所にはPCSCが増えたのでいいけど、一番下の「ワークスペース」の候補に出てこない。
チームプロジェクトと、ソリューションと、ワークスペースと、全部別のものなのか?

わからんので、OKしてみよう。
image

怒られた。

 

チームエクスプローラーのホーム画面に戻る。

image

image

追加ボタンを押して、ローカルに「PCSC」というフォルダを作って、VSTSのPCSCと関連づけた。

 

PcscSample02をPCSCフォルダの下に移動させるため、一度ソリューションを閉じ、エクスプローラでPcscSample02フォルダごとPCSCフォルダの中に移動。
チームエクスプローラーの「ソリューション」で、ワークスペースとして「PCSC」を選択し、「開く」で移動させたPcscSample02を開く。

とすると、自動的にソリューションが追加されるかと思ったが、そうではないようだ。

image

これで、入った。

image

 

続けて、プロジェクトを追加。

image

よくわからんが、赤い波線が出ているので、バインドの解除。

image

さっきはソリューションの追加だったが、今度はプロジェクトの追加になっている。
きっと、きっとこのやり方は正しくないんだろうと思うんだけど、やり方がわからん。

image

次の画面で、コメントを入力して「チェックイン」すると、ファイルが登録されたようだ。
実に、すっきりしないが、とりあえず登録できた。


そういうわけで、正しい使い方かどうかわからないが、プロジェクトを登録できた。

でも、Gitでいいなら、Gitでやろうと思う。

[nfc]PC/SCを試す (1)

個人番号カードといえば、Type-B。
Type-Bはまだやったことがないので、今のうちに触っておきたい。
Windowsだと、PC/SCで操作するサンプルがあるようだから、まずはPC/SCを試してみよう。


うちの環境は、こう。

  • Windows7 64bit
  • PaSoRi RC-S380/S
  • Visual Studio 2015 Community

 

まず、C#でプロジェクトを作る。
Windowsフォームアプリケーションだ。

その後、「ツール>NuGetパッケージマネージャー>パッケージマネージャーコンソール」を選択
こちらをインストールする。インストールの仕方は、リンク先参照(コマンドを打つだけだが)。
NuGet Gallery | PCSC 3.3.0

元のサイトにはExamplesもあるので、それを動かそうと思ったが、せっかくなのでMessageBoxに表示させる。
danm-de/pcsc-sharp

 

ここでソースを載せようとしたのだが、まだOpen Live Writerのプラグインが整備中のようで、貼り付け方がわからん。
Googleドライブに、CSファイルだけ置いた。
https://drive.google.com/file/d/0B2_3hJpJ5Ui2Qy12d2ZwUnVfdG8/view?usp=sharing

見るとわかるが、単にpcsc-sharpのCardStatus Examplesのコンソール出力をMessageBoxにしただけだ。
エラー処理も手抜きしている。
https://github.com/danm-de/pcsc-sharp/blob/master/Examples/CardStatus/Program.cs

取得できる、SCardProtocolとかSCardState、あとATRってなんだろうね?というところから調べていくのがよいですかね。

Firefox Windows 64bit版

うちはFirefoxがメインのブラウザ。
Windowsの64bit版が普通にダウンロードできるようになったということで、インストールした。

そのまま進めると、なぜかProgram Files(x86)にインストールしようとするが、気持ち悪いのでカスタムインストールの方を選んでx86がついてない方にインストールした。

タスクマネージャーで見てみると、

32bit版のとき
image

64bit版の時
image

うん、64bitだ。

 

フォルダを分けたので、32bit版とも共存できるようだ。
また、設定も同じファイルを見ているようで、立ち上げたときに見た目で区別できない。
デフォルトのブラウザになっていないので、その確認をしてくるから「あ、違うな」とわかる程度だ。

64bitのプログラムを作ったことがないので知識が少ないのだが、確か4タイプくらいに分かれていたと思う。
int型を64bitで扱うか32bitで扱うか、とか、そういうのだ。
Visual C++ の 64 ビットへの移行に関する一般的な問題
intとlongは、32bit。
size_t, time_t, ptrdiff_tは64bit(time_tはVC2005は32bit版では32bitだったが、今は64bitらしい)。
だから、そんなに使用するメモリが増えるというわけでもないか。

いや、そもそも64bit環境で32bitプログラムが動いていたのだから、そっちを考えるべきか。
WOW64 - Wikipedia
4GBのメモリ空間で動いていたのか。
なので、当たり前だけど、ポインタ変数も32bit。
今回は64bit版になったということで、ポインタ変数の分は少なくとも増えることになるな。

私がパソコン関係を知り始めた頃は、8bitがホビーユーザーで、16bitはビジネスユーザー、みたいな感じだった。
PC9801とか。
でも、今は64bitが普通になってきていて、Windowsも「64bitはドライバがなさそうだなあ」と敬遠していたけど、そうでもない。
あと10年もしたら、また変わってくるかと思うと楽しみですな。

2015/12/19

NFCの技術記事で書き残っていること

今年は、あまりNFCの技術的な記事を書いてないように思う。
FeliCa Linkのことは書いたけど、あれはFeliCaってよりは、デバイスの扱い方だった。
nRF52のことを書いているときもそうだけど、NFCタグの時に技術記事で書くことって、あまり残っていないと思っている。
UARTとかの通信プロトコルだと、送信して、受信して、が基本だ。
SPIだとマスターがクロックを持つし、I2Cもマスターから要求してこないと何もできない。
NFCの場合、親と子がきっちり分かれている(いや、そうしないところもあるか)。
BLEの場合は、サーバとクライアントが分かれている。
ちょっと、整理する。
image
(整理していないイメージ)

デバイスの扱い方

NFCの通信ができるデバイスを使う場合、だいたいホストとはシリアル通信で接続する。

UARTは、ホストとデバイスがほぼ対等だと思う。
RTS/CTSはあるが、それ以外はルールがほとんどない。
だから、あまり使われていない。

SPIは、クロックが動くと送信と受信が同時に動くのが多い。
私のイメージでは、ギアだ。
片方が動けば、もう片方が逆に動く。
FeliCa PlugはSPI風だった。

I2Cだと1本のデータ線を共通する。
こちらは、2車線の道路が工事中で、1車線になっているイメージ。
けど、送信と受信が同時に行われないシステムであればボトルネックにならない。
無線の通信なんかは、同じ周波数を一度に送信と受信が並列でやることはできないため、I2Cで十分なことも多い。
FeliCa LinkはI2Cだ。





WCDMAとかはよく知らんが、同じ周波数帯の衝突はNGというのが基本だと思っている。
あと、I2Cだと線が2本だけあればいいので、けっこうすっきりするんだと思う。
うまく通信できないときは、どっちが悪いのかはっきりせずにかなり苦しむのだけどね。
思い出したくないです。。


デバイスも、RC-S620/SのようにInitiatorにもTagにもなれるタイプと、FeliCa LinkのようにTag専用のタイプがある。
Tag専用の場合、相手から搬送波をもらってから動くので、搬送波検知機能が付いていることが多い。
また、相手に無線を出さないので、デバイス自体が小さくできる。
Initiatorになるタイプは、無線を出して相手を起こさないといけないので、アンテナが大きくなりがちだ。
FeliCa LinkもInitiatorになれるタイプがあるのだが、見たことがないので小さくもできるのかもしれない。

タグの扱い方

NFCの通信は、主従がはっきり分かれている。
  • Initiatorが主で、Targetが従。
  • Initiatorが無線を出す方で、Targetが無線を受ける方。
  • Initiatorが要求を出す方で、Targetが応答を返す方。
割り切ると、そう難しくはない。
Androidスマホは、だいたいInitiatorに当たる。
といっていた時代は、ずいぶん前のものになるので、もう少し現状にあわせよう。

Androidと、iPhoneが今の主なスマホという認識。
Windows Phoneは、私に知識がないので、今回は除外。
そしてAndroidもiPhoneも、最新の情報だけで見ていく。
BLEの視点ではiPhoneの方が先だが、NFCの視点ではかなり後ろになる。
後ろというか、提供していないので、比較できないというだけだ。
Appleは何をしているかよくわからないので、見えないところについては話をしないようにしておく。

Androidは、NFCを有効にしている場合、画面がON状態になると定期的にNFC-A/B/Fの搬送波を出してタグを検知しようとしている。
タグを検知すると、アプリの優先度によって、NDEFを検知したとかまで見てくれる。
Android APIを見ると、MIFARE Ultralight用のclassがあるので、ちょっと不公平な感じはある。
MIFARE ClassicはNFC Forumの標準には入っていないので、検知できない端末もある。

最近のAndroidは、HCE(Host Card Emulation)という、Secure Elementがないタグとして動く機能も持っている(Type-4Aとして動く)。
通常のタグは、Secure ElementというNFC通信でしかアクセスできないメモリを持っていて、そこに決済の情報(これをアプリと呼んでる)がある。
FeliCa LiteやMIFARE Ultralightのような安いタグは、そのメモリを保護する機能が緩いが、決済できるタイプのタグだと厳しくなっている。
厳しくなっているので、どういうアクセスができるかも情報が秘匿されていて、私みたいな一般人に知ることはできない。

Secure Elementは、携帯電話だと基板上にメモリデバイスとして載せるか、SIM内に載せるかのパターンがある。
FeliCaは前者なのだが、世界的には後者のタイプが多いらしい。
なので、海外製の端末ではNFC-Fとしての通信はできるが、FeliCaの決済としては使える端末がない(と思う)。
SIMに載っていると、携帯電話を変更したときにSIMだけ移動すれば決済の情報も移動できる。
できるのだが、使う際には携帯電話とSIMが通信をしてデータにアクセスすることになるため、速度が上げにくかったと思う(SIMとはSWPという1線で通信することが多い)。
なので、SIMに載せるとFeliCaの特長である高速アクセスができないんじゃないの、という話も出てた気がする。

HCEはそのSecure Elementをソフトウェアとして持つ。
そうなると、セキュリティ的に大丈夫なのかっていう気はするのだが、Secure Elementを持たないでよくなるので参入はしやすくなる。
Secure Elementはある意味で共有財産みたいなもので、例えばFeliCaだとフェリカネットワークスが管理している。
自分でアプリを作ってFeliCaのSecure Elementを使いたいと思ったら、フェリカネットワークスに申請して他と重ならないように領域を取ってもらう作業がいる(たぶんだけど)。
そこには、どうしてもお金が必要になってくるし、あまり安いものではないらしい。

HCEになると、それがいらなくなる(AndroidのHCEはFeliCa通信できないが)。
なので、今まで参入できなかったところもHCEで決済機能を持たせやすくなる。
今のところ、日本ではHCEで決済しているところはなさそうだ。

最後に

NFC Forumができたときには盛り上がったのだけど、最近はNFCっていうのがあまり目立たなくなってきた。
とはいえ、AppleがNFC Forumに参加したし、最近のiPhoneにはNFCが載っているらしいし、全体としてはNFCを使う下地ができつつある。

もうちょっと私がNFCを使う生活をしていれば違うのだろうけど、ほとんど使うことがないため、あまり世の中でどう使われているかを知らない。
ちょっと前は、FeliCa vs. NFC、みたいな記事もちらほらあったのだけど、最近はどうなのかね。
ネットで検索したけど、よくわからんかった。
SIMフリーの端末とか増えてきたので、FeliCaもSIMに入るようになるとは思うけど、スケジュールではどうなっていたか忘れてしまった。

けど、NFCで決済っていうことからすると、FeliCaとかMIFAREとかじゃなくて、NFCを使えばその辺を気にせず決済できる、というのがユーザの理想だろう。
派閥を争うんじゃなくて、使い勝手をよくしていく時期に入ったんじゃなかろうか、という感想を持った。

[nfc]個人番号カード

久しぶりに、NFC関連の記事を書いておこう。
今はやり?のマイナンバーカードについてだ。

image

 

うちにはテレビがないので、ネットでしか見てなかったのだが、来年1月からマイナンバーというものが使われるようだ。
そして、マイナンバーにNFC的な認証機能を持たせたものが、マイナンバーカードらしい。
目が「11」になったウサギがキャラクターっぽいのだが、どういう意味だろうか?

制度がどうのこうのという話は抜きにして、マイナンバーカードの話だけをしてみる。
といっても、別に私は行政のことを知ってるわけでもなく、単にNFCをかじっているだけなので、マイナンバーカードのことだけをネットでさらって書いてみよう。


まず、似たような言葉があるので、整理する。

  • マイナンバー
    • 「個人番号」ともいう。
    • 単に、割り当てられた番号を指す。
  • 通知カード
    • 郵便で配られた、マイナンバーが書かれたカード。
    • 「マイナンバーを証明する書類」として使える(通知カードと同梱の資料より)。
    • 「本人確認の際の身分証明書」としては利用できない(通知カードと同梱の資料より)。
  • 個人番号カード
    • 「マイナンバーカード」ともいう。
    • 「通知カード」とは別物。
    • 「マイナンバーを証明する書類」として使える(券面)。
    • 「本人確認の際の身分証明書」として使える(券面、電子証明書)。
    • 申請しないと入手できない。

というわけで、マイナンバーは数字、通知カードはマイナンバーが書かれたカード、個人番号カードは通知カード+α、という感じだろうか。

通知カードも、個人番号カードも、マイナンバーが基本にある。
だから、受け取りを拒否するニュースがときどき見られるが、「マイナンバー制度」がある限りはあまり意味がないことになる。

番号が付くのを嫌がる感覚はわかるが、ログインとかアカウントとかをしょっちゅうやっているので、内部で共通に扱っていたものを公開しただけなんじゃないの?という気もする。
まあ、だからといって気持ちがよくなるわけではないし、これにたかってくる人々もいそうだからすっきりはせんが。

いかんいかん、技術的な話に戻ろう。


さて、個人番号カードだ。

同梱の資料に「個人番号カード メリット」で検索するように書かれているので、リンクだけ貼っておこう。

あまり検索に詳しくないので、確かYahooはGoogleと同じエンジンだったような気がするけど、何か違うかもしれんしね。

自分の話をすると、個人事業主になって確定申告をするときに、住基カードを取得しようかと思っていた。
あれがあると、PaSoRiで家から確定申告の送信までできるという話だったからだ。
でも、あれは取得に500円かかるし、有効期間が短かったと思う。

それが、個人番号カードが代わりになり、しかも初回交付手数料は無料らしい。
(紛失その他に伴う再交付手数料は有料らしいが。)
なので、今回は申請した。

といいつつも、主な目的は、個人番号カードにNFCが搭載されていることにあった。


NFC。
Near Field Communication。
流行ったような、流行らなかったような、安定したような、そうでないような、あまり今の扱いがわかっていない。
日本では、nimocaSuicaなど、FeliCa系は安定している気がする。

image

image

Suicaのペンギンもいいけど、nimocaのフェレットはかわいいと思います(個人の感想です)。

 

以前は、「NFC=海外」「FeliCa=国内」というイメージが強かったと思うが、最近はそこまで極端な記事はなかったような気がする。
でも、オリンピックが東京で行われるらしいし、海外の人が日本に一斉に短期間でやってくることを考えると、「みんなnimoca/Suica買ってねー」というよりも、「スマホとかで決済できる人は使ってねー、それがない人は買ってねー」の方が現実的じゃないかと思う。
いや・・・無駄に買わせたい人々がいたらわからないのだが・・・。

でも、今から確か5年後くらいだから、そこは「シームレス」だった方が格好がよいと思う。
買うのは、お土産目的とか、そういうくらいで、ね。
あと4年くらいしかないと思うけど、2010年くらいで今の状況は予測できなかったと思うから、2020年も予測できないくらいのことを考えておかないと、面白くないと思う。


また脱線したが、個人番号カードに戻ろう。

個人番号カードは、住基カードの後継になるようだ。
入手はしていないが、住基カードはType-B規格だったはず。
パスポートも、運転免許証も、Type-B。
日本だけで使うのだったら、NFC-Fというか、Type-C(幻)というか、FeliCaでやればよかったんじゃないの?という気はする。
事情通なら、「実は・・・」みたいな話ができるのだろうけど、あいにく私は何も知らない。

Androidアプリに、運転免許証を読み込むものがあったけど、うちのNexus5/7ではうまくいかなかった。
そういうわけで、Type-Bというのは、なんとなく「普通では読み込めないもの」というイメージがある。

Sony Japan | FeliCa | 法人のお客様 | 製品情報 | PaSoRi(パソリ)製品比較表
こちらによると、RC-S380はマイナンバーカードに対応している。
以前の主力であった370は、廃型なので載ってない。

 

うちにもRC-S380はあるので、来年になってカードを入手できたら、試してみましょうかね。

[nucleo]AndroidでUSB Serialからログを見ようとしたが失敗した

うまく行かなかったシリーズだ。

先週、お客さんのところでNUCLEOのログを見る機会があった。
NUCLEOは、mbed enabledの基板は全部そうなのかもしれないが、USBクライアントとして接続することができ、USB Mass Storageとして見えつつも、USB Serialとしても見える。
STM32のシリアルポート接続を、NUCLEO側のシリアル接続とつなげることで、間にコンバータを入れずともUSB接続だけでログを確認できる。
便利だ。

ただ、作業が長引いてしまったため、私のノートPCの充電が切れてしまい、ログを見届けることができなかった。
この辺は、お客さんのところに出向いて作業するというスタイルが確立していないがために発生した失敗だ。
反省して、ACアダプタは持っていくことにしよう。

 

とはいえ、ログだけ見たいのにノートPCをわざわざかついでいくのも、四十肩の私にはつらい。
お客さんのとこに行くときはNexus5を持ち歩いているので、それだけでログを見れるようになっておくと緊急時にも役立ちそうだ。


そういうわけで、まずはWireSharkを使って、どういう制御をすればNUCLEOとシリアル通信できるか調べようとした。
いつものようにWireSharkでログを取った。
もしかしたら、単なるWinUSBドライバにしていてもデータが流れてくれないかなー、と期待して、zadigでドライバを差し替えようとした。
Windowsの場合、zadigでWinUSBに切替え、libusbであれこれ操作すれば、だいたいのことができるのだ。

が、NUCLEOをWindowsはUSBシリアルの標準デバイスとして認識しているようなのだ。
USBシリアルの標準といえば、CDC。
であれば、わざわざプロトコルを調査したり、アプリを作ったりしなくても、Androidアプリが存在するんじゃなかろうか?

 

いくつかアプリを試したが、だめだった。
一番有力だったのが、こちら。
https://github.com/mik3y/usb-serial-for-android
そのままではデバイス自体見えなかったので、VID/PIDを指定して接続したものの、JNIのところで「init」「close」を繰り返している。
ネットで検索すると、そういう人がいたのだけど、Androidのバージョンが上がったら直ったとか、そういうのしか見つけられなかった。
電源が足りないのかと思って、セルフパワーなUSBハブを使ったけど、症状変わらず。
むぅ。

めんどくさくなって、スイッチサイエンスさんから購入していたProfilicの変換ケーブルを使うと、USB Serial Terminal Liteというアプリでログを見ることができた。
もう、これでいいや。

技適の検索

nRF52 Preview DKは、技適を取っていない。
ということを考慮せずに購入してしまったので、もうちょっと敏感になろうと思う。
まずは、技適を取っているかどうかの検索からだ。

 

総務省 電波利用ホームページ | 技術基準適合証明等を受けた機器の検索

image

入力できるのは、これら。

  • 氏名又は名称
  • 型式又は名称
  • 年月日
  • BODY SAR対応
  • 番号

 

まず、いつもつかっているBVMCNDT52を調べよう。
Rを四角で囲んだ番号が見えるので、それを「番号」の方に入力する。

007-AC0039
image

見つかった。
リンクをクリックすると、詳細情報が確認できる。

image

 

では、これをハイフン無しで入力したらどうなるだろう?

007AC0039
image

厳しいな。
では、「氏名又は名称」で検索してみよう。

braveridge
image

「Braveridge」や「株式会社Braveridge」「株式会社Braveridge」もOKだったが、「株式会社 Braveridge」はだめだった。

買った後であれば番号を見て入力できるが、買う前は番号がホームページとかに載っていなかったら難しい。
「氏名又は名称」で検索するのがよさそうだ。

 

では、BLE Nanoを検索しよう。
いろいろ番号以外で検索しようとしていたのだが、どれも検索できなかったので、あきらめて番号で調べた。

image

RAYTAC 勁達國際電子
こちらになるらしいが、これはわからんなぁ。
MDBT40はモジュールの名称なので、まだこちらの方が検索しやすかったかもしれない。
が、Braveridge社の方はモジュール名が載っていないので、同じルールでは検索できていない。
うーむ・・・。

 

無線の認証は他の人がやっていたので詳しくないのだが、無線を出すIC本体ではなく、無線の出し方を制御する部分として認証を取る感じだったと思う。
だから、nRF51822の認証ではなく、アンテナとして組んだBVMCN51とかMDBT40とかで認証を取っていて、BVMCNDT52とかBLE Nanoとしては取らない。
2.4GHz帯の仕様をよく知らんのだが、SoftDeviceを書き換えても問題はないのかな? ないのだろうね。
他の周波数帯から見ると、好き勝手やれるなー、というイメージがある。

だいたいTELECとか認証取るときは時間がかかるので、その間にソフトが変更になることは普通だ。
だから、認証担当の人がちゃんと説明したりとか、追加のテストとかしてるのかもしれない。

 

というところまで書いて、技適とTELECって同じものなのかどうか気にしていなかった。
技適は、技術基準適合証明の略。
TELECは、技術基準適合証明の証明機関の1つらしい(技術基準適合証明 - Wikipedia)。
だから「技適を取るためにTELECでテストする」ということか。
TELEC以外にも証明機関はあって、TUVみたいな有名どころが載っていた。
TUVってカナダの証明機関かと思ってたけど、単にカナダに輸出するときにTUVを使ってたんだな、と今になってわかる。。。

 

無線は共有財産なので、人の邪魔にならないようにせんといかん。
モジュール開発中は技適が取れていないので、電波が他の邪魔にならないようにしておかんといかん。
無線暗室とかあればいいんだけど、何十人も開発するときや、広範囲での動作確認をしたいときにはそうもいかない。
そういうときは、野球のグラウンドを借りたり、砂丘みたいな広いところに行ったりするみたいだ。
(そこまでやったことはないので、実はちゃんとやる前に申請とかしてるのかもしれないし、そもそも冗談話とかかもしれん。)

 

そこら辺を検索していると、福岡市で特定実験試験局制度を緩和するという申請をしている話が見つかった。
続報がうまく見つけられていないのだが、緩和が認められる方向になっているようだ。
そうなると、申請とかはいるだろうけど、今よりはやりやすくなるだろうね。