2016/09/29

CUDA 8が正式リリース

CUDA Toolkit | NVIDIA Developer

ようやく、CUDA 8が正式リリースされました。
と、わざわざ書くと、私がcaffeとかですごくCUDAを使っていて毎日監視しているように見えますが、単にNVIDIAからメールが届いただけでした。

 

うちがXubuntu16.04環境なので、Ubunt16.04で使えるものがアカウント無しでダウンロードできるようになったというのがありがたいです。

最近やっていないから、また忘れてしまった。。

Arduinoライブラリをどうしたらよいかだんだんわからなくなる

最初、あまり読まずに私がC++でやるときのルールで実装していった。

  • 公開する整数定数は、publicのstatic constに書く
  • 同じく、enumもpublicに書く
  • 最初に設定したら変更しないものは、コンストラクタでもらうようにする
  • コンストラクタでオブジェクトのポインタをもらうなら、参照でもらうようにすることも考える

 

そう実装してから他のライブラリをちらっと見たのだが、そういう実装ではなさそうだった。

  • 定数は#defineにする
  • enumは使ってない?
  • 参照を使っているところは見つけられなかった

 

Arduinoとしてはマクロはあまり使わないようなことを書いていた気がするのだけど、今見直したら書いていないな。
マクロ名も、クラスに関係しているかどうかとか気にせず、やたら短かった。
あんまり短いと、誰かとぶつかって困る羽目になりそうなのだが。。。

 

結局私も、static constやenumはやめて、#defineに置き換えることにした。
ただ、短い#defineだと衝突しそうなので、クラス名の一部をプレフィクスに付けた。
多少はましだろう。

 

あまり時間を掛けたい作業ではないのだけど、ルールがあるものは仕方が無い。
全部に従うことは無いにしても、不自然で無いようにはしたいものだ。
が、自信はないな。。。

2016/09/27

Arduinoっぽいコーディングを調べる

Arduinoライブラリを作ることになったが、そもそもArduinoをあまり使ったことが無い。
どういうルールで書くとそれっぽくなるのだろう?

 

Arduino - StyleGuide
Arduino - APIStyleGuide
短いけど、読みづらい。。。。
幸い、日本語で訳している人のページがあった。
他のライブラリを見た調査もあって、ありがたい。

Arduinoのコーディングルールと命名規則を調べてみた - Qiita
「個人的にあまり納得のいかないルールもあった」ということだが、どれどれ。。。

ああ、なるほど。
ちょっと、すっきりしないな。。。
まあ、C/C++言語ではなく「Arduinoで使う言語」と割り切るのがよいだろう。

 

整数型の型として、uint32_tのようなものではなく、unsigned longなどを使うよう推奨している。
間違えそうなので、メモ。

整数型以外は省略する。

普通のGCCを使っているようなので、uint32_tなども使うことはできる。
が、推奨はしていないので、少なくともAPIとしては使わない方が良いだろう。

 

また、引数でポインタを取るくらいだったら配列で指定するよう推奨している。

int getName(char *pName)  -> int getName(char[] pName)

配列を引数に取る関数って、そういえば書いたことなかったな。。。
どっちにせよ、C言語としては値渡ししかないので、アドレス値が渡されるだけのことだ。

だまされたっ!

int getName(char *pName)  -> int getName(char pName[])

C/C++なんだから、配列の括弧は名前の後ろじゃ。
公式サイトが間違っているのだけど、なんでこのままになってるんだろう?
実はみんな、普通にポインタで渡してるんじゃないのか??

 

あれ、ということは、参照でもらうのはよろしくないということかい。。。


気になっていることとして、文字列をどう扱うのがよいか、というものがある。
char配列がよいのか、std::stringがよいのか。。

Arduinoのリファレンスページを見ると、「string」と「String」があった。
stringは型ではなくて、char配列を指していた。
Stringはclassで、あるバージョンから使えるようになったらしい。

 

char配列の方は、普通のchar配列のようだ。
でも、一番下にあるExamplesで、

char* myStrings[]={"This is string 1", "This is string 2", "This is string 3", "This is string 4", "This is string 5","This is string 6"};

となっていた。
"文字列"のところは文字列定数だから、const型なのだけど、const無しで受けている。
g++でコンパイルしてみると「deprecated conversion from string constant to 'char*'」の警告が出る。
いくらC言語初心者でも扱えるようにとはいえ、あまりよろしくないと思う。
「お、char型だから書き換えられるやん」、と思って変更すると、ROM領域へのアクセスになるから、何も起こらないか、不正アドレス操作で死んでしまうか、そういう期待しないことになるだろう。

 

一方のString型だが、c_str()があるなどstd::stringっぽい。
新しく作ったということは、こっちを使ってほしいのだろうか?

いや、今回ね、APIから文字列を返すことになるかもしれないのだ。
一時的な文字列だったらライブラリで文字列のメモリを持ちたくないので、戻り値ではなく引数で受け渡しすることを考えていたのだ。
その際に、char配列がよいのか、Stringオブジェクトを参照でもらうのがよいのか、迷いがある。

中身をもらう必要は無いので、コピー渡しにはしたくない。
だから、ポインタか参照で考えていたのだけど、Arduinoで参照型を使っている例があるのかなあ。

それに、私のルールでは、constの参照渡しはするけれども、値を書き換える場合はポインタで渡すようにしていたのだ。
見分けが付きにくいから、というだけの理由だが。
C#みたいにoutとかあるといいんだけどね。

 

うーん、もう少し悩んでみます。

2016/09/26

Arduinoのライブラリを作る

お仕事でArduinoのライブラリを作ることになった。
作る内容はさておき、そもそもどうやってつくるんじゃ?というところを調べておこう。
仕事の内容はネタにできないが、こういう一般的なものであればネタにできるのだよ。


いま(2016/09/26時点)のArduino IDEは、v1.6.12のようだ。
Web Editorというものもあるようだが、IDEでやる。
私はWindows10を使っているので、以下もWindows版についてとなる。

 

IDEでスケッチを作ると、拡張子は.inoになるが、ライブラリは普通のC++形式で作ればよいようだ。
ちなみに、IDEでcppやhを読もうとすると怒られる。

image

テキストエディタで作って、サンプルだけIDEで作ってビルドすることになるか。
ライブラリだからと言って.aとかにするわけではなく、ソース提供するだけになるみたいだ。

 

作る場所は、どこがよいか。
How to write libraries for the Arduino?」では「hardware\libraries」に置きそうなことを書いてあるが、そういうフォルダはない。
だいたい、XPとか書いてあるので、ずいぶん前のことじゃなかろうか。。。

Program Filesに置くものでも無いので、スケッチを置くフォルダが妥当だろう。
最初から「libraries」というフォルダはあるのだが、これはライブラリをインストールしたら配置されるようだ。
ただ、これもIDEがv1.0.5となっているから、古い可能性がある。
試しておくか。

 

まず、librariesフォルダの中に「hiro99ma」というフォルダを作り、Arduino IDEを起動する。
うん、「スケッチ>ライブラリをインクルード」には出てこない。

image

では、この中に「hiro99ma.h」という空ファイルを置いて、IDEを再起動する。
出てきた。

image

「インクルード」だから、ヘッダファイルだけあればよいということか。
選択しても、スケッチの先頭にincludeされるだけのようだ。


では、中身がないうちに、ビルドするexamplesスケッチも用意しておこう。

Arduinoがインストールされるフォルダの中にあるlibraries(うちでは「C:\Program Files (x86)\Arduino\libraries」)には、IDEインストール時に提供されたインクルードできるライブラリが入っているようだ。

見てみると、だいたいがライブラリ名のフォルダの中に、以下が置かれていた。

  • examplesフォルダ
  • srcフォルダ
  • keywords.txt
  • library.properties
  • README.adoc

srcがなく直下に置いてあるもあるし、README.adocじゃなくてreadme.mdのもあったが、まあ傾向としてはこうなっていた。

では、先ほどの「hiro99ma.h」も、srcフォルダを作って移動させて、インクルードする一覧に出てくるかやっておく。
・・・出てこない。
これはちょっと、IDEがよくないと思うが、どうだろうか。

ひとまず、srcフォルダは作らず、直下にソースファイルを置いていく。


こういう構成にした。
examplesにtest1フォルダを作り、その中にtest1.inoというビルド用スケッチを置いた。
hiro99ma.hとhiro99ma.cppは、hiro99maフォルダの中に置いている。

image

順番に、hiro99ma.h、hiro99ma.cpp、test1.inoの内容。


#ifndef HIRO99MA_H__
#define HIRO99MA_H__

class hiro99ma {
public:
    hiro99ma();
    virtual ~hiro99ma() {}

    void hello();
};

#endif /* HIRO99MA_H__ */


#include <Arduino.h>
#include "hiro99ma.h"

hiro99ma::hiro99ma()
{
}

void hiro99ma::hello()
{
}


#include <hiro99ma.h>

void setup() {
  // put your setup code here, to run once:
  hiro99ma h9m;
  h9m.hello();
}

void loop() {
  // put your main code here, to run repeatedly:

}


この内容でIDEの「検証」を行うと、エラーは発生しなかった。
試しにhiro99ma.cppを抜いてみると、ちゃんとエラーが発生したので、ビルドしているようだ。

ただ、IDEでtest1.inoを変更して保存しようとすると、書込禁止扱いになってしまった。
テキストエディタでは編集できるし、ファイルの属性も問題なさそうなので、libraries以下にあるものは書込禁止扱いにしているのかもしれない。

また、もしかしたらcppファイルはsrcフォルダに置いてもビルドしてくれるのではないか、と期待したが、ダメだった。
では、zipファイルに固めたらいけるんじゃなかろうか?

単純にzipにすると、まずライブラリとして受け入れてくれなかった。
library.propertiesファイルを置いて、適当に埋めると、インストールに成功した。
見え方は、さっきのインクルードと同じ。
ちゃんと、librariesフォルダに「hiro99ma」が展開されていた(zipインストール前に作っていたフォルダは消しておいたので、新たにインストールされたものだ)。

zipはこういう構成で、Windows標準のZIP圧縮で固めただけだ。

hiro99ma
│  library.properties

├─examples
│  └─test1
│          test1.ino

└─src
        hiro99ma.cpp
        hiro99ma.h

ちゃんとexamples\test1も「ファイル>スケッチの例」に入っていた。
ビルドすると、library.propertiesのcategoryを適当に書いたため警告が出たが、エラーは出なかった。


あれ、じゃあ、library.propertiesを置いておけば、zipじゃなくてlibrariesフォルダに置いておいてもsrcにCPPファイルを置いておけたんじゃないだろうか?

だめだ・・・。
インクルードできるライブラリの一覧に出てこない。

あまり納得できんが、zipでインストールしたときだけsrcフォルダが有効になると言うことと覚えておくことにする。

2016/09/25

[nrf52]Secure DFU Bootloaderを試す (2)

みんな忘れていたと思うし、私も忘れていたが、前回の続きだ。
体調がよいときに書いておかねば。。

今は、SoftDevice S132 の v3.0.0が焼かれている(nRF5 SDK v12に入っていたもの)。
nRFgo Studio v1.21.2ではまだバージョンが出てこないようだ。

image

(今気付いたが、SDKに入っているビルド済みHEXファイルは、SoftDeviceも含んだ形なんだな。)

 

examplesのBLE Secure DFU Bootloaderをgccでビルドするのと、DFUで送るZIPファイルを作成しようとするまでが前回だった。

まずは、ZIPファイルの作成を行う。
公開鍵はブートローダに埋め込んであるので、指定する秘密鍵もそれに対応するものでないとダメだろう。
が、秘密鍵と思われる情報がSDKに入っていないので、自分で作るのは無理そうだ。
自分で秘密鍵から作るのは後にして、examples/dfu/ble_dfu_send_hexに入っているファイルを使おう。
名前からすると、HRMサンプルのようだ。


では、ファイルは準備できたので焼いていこう。

まずは、ブートローダをnRF52832に焼く。
これはnRFgo Studioを使う。
タブの一番右が「Program Bootloader」なので、それでよいだろう。

image

以前のブートローダと同じく、一番後ろに配置された。

 

次に、ZIPファイルをスマートフォン側に置く。
dfu_test_app_hrm_s132.zipを使うことにした。
うちはAndroidで、nRF Connectをインストール済みだ。

 

nRF52832をリセットしてやると、ブートローダが見える。

image

CONNECT。

image

右上のDFUをタップ。

image

ZIPでOKし、置いたZIPファイルを選択。

image

うまくいった。

が、これだと何だかわからないので、普通にZIPファイルを作った場合もやっておこう。

> nrfutil pkg generate --application nrf52のHRSサンプル.hex test.zip

"--key-fileが無い"と怒られた。
そして、以前のdfu genpkgは無くなっているようだ。
しょうがないので、nRFgo Studioの中に入っているnrfutilを使って作成。

あー、そしてちゃんとしたapplicationが焼かれているとブートローダは動かないので、ボタン4を押しながら起動しないといかん。
BUTTON_4は16になっているので、GPIO16とGNDをスイッチで接続(内部でプルアップされてるはず)。

ボタンを押しながらnRF52を起動するとDfuTargが見えるので、同じ手順でDFUを実行。
そうすると、グラフの画面までは進むのだが、すぐに切断されて終わった。
うん、まあうまくいったというか、うまく失敗したと思ってよいのかな。


では、自分で秘密鍵を作るところからやってみよう。
書いてあるとおりにやる。

$ nrfutil keys generate priv.pem
Generated private key and stored it in: priv.pem
$ nrfutil keys display --key pk --format code ./priv.pem --out_file dfu_public_key.c
$

できたdfu_public_key.cをオリジナルと置き換えてmake。

できたpriv.pemを使って、HRSサンプルのZIPを作成。

$ nrfutil pkg generate --application nrf52832_xxaa.hex --key-file priv.pem test2.zip
Error: --hw-version required.

まだダメらしい。
表では例として52とあったので、nRF52の52なのか。
ただ、これを指定しても、--sd-reqと--application-versionが要求された。

$ nrfutil pkg generate --application nrf52832_xxaa.hex --key-file ../priv.pem --hw-version 52 --sd-req 0x8c --application-version 0xff test2.zip
Zip created at test2.zip

0xffにするとスキップされるようだが、--sd-reqはよくわからん。
nRFgoで表示されたFirmwareのIdが0x008cだったので、そうしてみた。

これでブートローダを焼いてやってみると・・・だめだった。
さっきと同じで、すぐに切断されてしまった。
ちゃんと読もう。

・・・うん、どうもブートローダをpca10040_debugの方でビルドしたのがよくなかったようだ。
ifdefでNRF_DFU_DEBUG_VERSIONを見ているようで、先ほど置き換えたdfu_public_key.cも、おそらくifdefで分けられていた。
ソースの方でも使っていたので、何かあるのだろう。

ともかく、ブートローダをpca10040の方でビルドして焼き直すと、作ったZIPファイルでDFUできた。
examplesに入っていたZIPファイルを指定すると、ちゃんと失敗するので、うまくいっているのだろう。

[ble]Secure Gateway Kit

Windows10 64bit環境に、Secure Gateway Kitをインストールして動かした。

  • Bluetoothドングル : Planex BT-Micro4
  • Node.js : v4.5.0のwin-x64
  • Visual Studio 2015 (Community?)
  • Python 2.7

VSとPythonはインストール済み。
zadigも既にある。

 

Node.jsを適当に解凍。

管理者権限でコマンドプロンプトを開いて、Node.jsにパスを通し、インストール

> npm install --global --production windows-build-tools

ScriptAndSourceCodeでコマンドプロンプトを開いて、Node.jsにパスを通し、インストール

> npm install bluetooth-hci-socket
> npm install -g node-gyp
> npm install noble

Node.jsをよく知らないのだが、npm installはコマンドプロンプトと同じ場所にインストールするのかな。
「node_modules」というフォルダができていた。

そして、ScriptAndSourceCode/gatewayで管理者権限のコマンドプロンプトを開き、インストール。

> npm install

別の管理者権限のコマンドプロンプトをScriptAndSourceCode/navibleで開き、インストール。

> npm install

そして、それぞれのコマンドプロンプトで開始させる。

> npm start

そうすると、navibleの方にアクセスするURLが出てくるので、ブラウザで開く。
ユーザ名とパスワードを訊かれるので、とりあえず両方に「user1」を打ち込むと、こういう画面が表示された。

image

赤いところにはMACアドレスが表示されている(たぶん、お隣さんのデバイスだと思うので隠した)。
nRF52を起動させて、右上の「Scan」を押すと、少しぐるぐる回るアニメーションが出た後、更新された。

image

 

Nordic_BDSをクリックすると、詳細画面に遷移した。
横幅を狭くするとレイアウトが崩れるので、ほどほどに広くしたほうがよい。

image

Connectをクリックすると、ちゃんと接続された。

image

一番下が自作のServiceなのでクリックすると、展開される。
レイアウトが、どうやっても崩れてしまう。。。
Firefoxだからかと思ってChromeに変更してみたが、同じだ。

image

また、ReadやWriteしても、うまく行かなかった。
でも、Generic AccessのDevice Nameは読めたので、なんかあるのか、単にnRF52に焼いているソフトが変なのか。。。

 

nRF52にHRSサンプルを焼いたが、うーん、やはり動きがあやしい。

値の表示を「string/hex/byte」で切り替えられるのだけど、うまく切り替わらないことがある。
たとえば、Generic AccessのAppearanceをstringでReadすると「A」と表示され、hexにすると「41 03」、byteにすると「65, 3」になるのだけど、最初から「hex」でReadしても「A」なのだ。
ここは、Readした後で切り替えるもの、と思っていた方がよい。

Notificationの有効化はうまくいくようだ。
Heat Rate MeasurementのNotifyにチェックすると、ぱらぱらと値が変わっていた。

しかし、しばらく接続していると急に切断されるようだ。
ブラウザは接続中のままなので、HCIとかそっち側かもしれない。

使えるかと思ったが、うーん、ちょっと微妙な感じだ。
BT-Micro4以外で試せないので、他ので試すとうまくいく、というパターンかもしれない。
サポートしているUSBドングルは、これらとのこと(BT-Micro4は、CSR8510 A10として見えていた)。

develop with blue

Bluetooth SIGに「新機能!」という項目があったので見ていた。
毎日見ているわけではないので、ずいぶん前からあったのかもしれない。。

https://www.bluetooth.com/develop-with-bluetooth/developer-resources-tools

最初に開くと日本語ページだったのだが、サイトの上からEnglishを選んだ方がよい。

「develop with blue」になって、Starter Kitやら、Secure Gateway Kitやらがあった。
いつの間に。

 

Starter Kit

これは、Arduino 101というものらしい。
検索すると、ずいぶん前からあったようだ。
スイッチサイエンスさんにもあった。
アメリカでは"Arduino"で、それ以外の国では"Genuino"だそうだ。
3.3Vというのが、よいですな。

Application Accelarator2.1やBeacon Smarter Kitもあるが、これはこのStarter Kitに対して使うもののようだ。
Accelarator2.1だけダウンロードしたのだけど、Bluetooth Developer Studioのようなものではなく、サンプルソースが入っているだけのようなのだ。
まあそれでも、Windows10でのBLEアプリは作り方を知らなかったので役に立ちそうだ。

 

Secure Gateway Kit

こちらは何も書いていないので、仕方なくダウンロードした。
名前とメールアドレスを入れるだけなのだが、その手間がめんどくさい。。。

解凍すると、PDFとJavaScriptたちが見えた。
どうやら、Raspberry Pi(2 or 3)のBluezとNode.jsをインストールして使うようだ。
こちらはBluetoothSecureGateway-HandsOnLab.pdfに載っていた図だ。

image

PDFの後ろの方に、Windowsにインストールする場合について書かれていた。
zadigを使わせるなど、なかなか楽しいやり方みたいだ。
Node.jsは普通にインストールさせているから、Bluezが使えない分をまかなっているようだ。

ということは、Raspberry Piじゃなくても、Linux系だったらそのまま使えるのだろう。
BluezとNode.jsが動けばよいのかな。

 

中身を余り見ていないのだが、CC2650 SensorTagの管理画面がブラウザで見えているから、BLE peripheralを登録して管理できるのだろうか。
GatewayがPeripheralたちとの仲立ちをして、Explorerで管理、というやりかたか。

図のSecure CommunicationとUnsecure Communicationは、単にペアリングのことを指しているような感じがする。
ただ、Secure Pairingと書いてあるし、BLE Legacyも別に書いてあるので、Core v4.2で追加された"LE Secure Connections"もちゃんと扱えるよ、ということかもしれない。


うちには、PlanexのBT-Micro4というドングルがあるのだが、これでもv4.2がいけるのだろうか。
ドングルってプロトコルスタックを自分で持ってないような気がするので、もしそうならソフト側だけ変更するといけるんじゃなかろうか。

うちのデスクトップPCはBLE開発はできるものの、BLE通信についてはnRF51やTIのドングルを使って読み取るくらいしかやっていないので、使えるのであればありがたいのだ。

2016/09/24

[nfc]どうやるつもりだろう

iPhone7の分解記事も出たことだし、どういうしくみでSuicaを動かすのか想像だけしてみよう。
まあ、今まで外してきたので、今回も外れると思ってるけどね。。。
iPhoneに興味は無いが、しくみには興味があるので、予想くらいはしておこう。

 

まだ日経さんの方は出ていないが、iFixitさんの方では分解していた。
モバイルFeliCaチップのことが書かれていなかったのでわからんねー、というのが前回だ。

まあ、せっかくだからNXPのコントローラしか載っていなかったということにしよう。
このチップは、たぶんType-Aのエミュレーションがデフォルト動作になってるんじゃなかろうか。
NXPといえばType-Aだから、という理由だが。

67V04と書いてあるが、一昔前は、PN544がよく使われていたと思うので、たぶん後継チップだろう。
iPhone6は65とかじゃなかったっけ。
位置づけとしては、このチップがいわゆるモバイルFeliCaチップに相当する。

このチップが、NFCアンテナとか、SIMとか、SEメモリとかにつながっていると思う。
セキュアエレメントは、だいたいSIMに載っているか、ボード上のメモリとして載っているかだろう。
FeliCaは後者ですな。
GSMだったか3GPPだったか忘れたけど、あっち側の規格ではSIMに置くこととなっているので、FeliCaもそこに入るためにはSIMにも置けるようにならんとね、というのが、ドコモとかが進めていたステップだと思う。
「SIMに置くことになっている」というのは、ドキュメントを読んだわけではなく、どこかの記事に書いてあっただけなので、本当かどうかは知らん。

 

NFCコントローラがNXPだろうとSonyだろうとBroadcomだろうと、だいたいどれもType-A/BやFeliCaにアクセスはできる。
周波数は一緒で、通信の方式が違うだけだから、使えなくするほどでもないか、ということかもしれん。
RC-S390だって、Edyに課金できるしね。

だから、FeliCaに67V04がアクセスできるのは当然なのだけど、今度はカード側にならないといけないので、エミュレーションしないといけない。
モバイルFeliCaチップはデフォルトでFeliCaになれると思うから、67V04はType-Aのみなんじゃないか、と考えている。
Type-BもFeliCaもエミュレーションするのは、面倒なんじゃなかろうか。

 

ちなみに、R/WタイプのNFCコントローラもカードエミュレーションできるが、こっちはデフォルトで動くことができないので、開始時に「Type-Aだったら、こう。Type-Bだったら、こう。FeliCaだったら、こう」みたいな指示を最初に出しておく。
「こう」と言っても、最初は必ずカードの有無を検出されるところから始まるので、相手から検出されようとしたらこれを返す、という指示をするだけだ。

その後は、受信するたびにいちいちホスト側のCPUが受信データを解析して、返信データを作ってやらないといけない。
PN544なんかは「デフォルトでType-A」と書いたが、つまりホスト側のCPUを介さずに勝手に処理してくれる、という意味だ。

このデフォルト動作を全部組み込まさせるのは大変だろうと思うので、67V04もType-Aだけなんじゃないかな、と思ったのだ。

 

じゃあ、改札側のR/WがiPhoneの場合だけType-Aでアクセスしに来ればいいやん、という感じもするが、まあ無理だろう。
FeliCaが来るかType-Aが来るかわからないので、R/Wは交互に切り替えながらやることになるだろうけど、そんなことをしていたらかざす時間が間に合わないと思う。
全国の改札を一斉に変更するのも大変だろうし。

だから、改札はFeliCaアクセスだけで、従来と変えていないと思う。

 

じゃあ、やっぱりiPhone側がSuicaアクセスをエミュレーションしないといけないことになる。
にもかかわらずモバイルFeliCaチップが載っていないのだったら、ホスト側ががんばってエミュレーションするんじゃないだろうか。
私の中で「HCE」はAndroid用語になっているので使わないけど、そういうことをやるんじゃなかろうか、という予想だ。

 

そうであれば、日本向け対応といってもハードウェアから変更したわけじゃないので、関係者さえ納得すればソフトウェア対応だけでいけるという気はする。
まあ、対応するのは少々じゃないとは思うけど。

iPhone6のときは、セキュアエレメントにお金の情報が直接入っているわけではなかったと思う。
あんまり私はわかっていないが、トークンとかそういう言葉で説明していた気がする。
5分でわかる iPhone6の新機能“Apple Pay”の仕組み - 週刊アスキー

お金の支払いでネットを使えたけど、改札だとその場で決済というか、お金を引いていくから、しくみが違いそうだ。
iPhoneで支払ったからと言って、Appleが儲かるわけでもなさそうだし、使用者の情報を得られるわけでもない気がするし。

メリットがよくわからないけど、裏で何をやっているか知らないし、お金持ってそうだし、いろいろ戦略がありそうだし。
母屋を取られるようなことにならなければよいのだけど、私が心配しても仕方ないですな。

 

誰かが試して調べてくれるだろうから、予想はここまでにしよう。
少しくらいは当たってくれてもよいと思うんだけどねぇ。

[c/c++]私のC言語 (失敗談) - リンカオプションが残っていた

たまには、失敗談でも書こう。
失敗をたまにしかしないのではなく、失敗談をたまにしか書かないだけだ。
今まで、けっこうミスをしてきたので、ミスが起きたときに「ああ、あれね」でわかることもあり、あなどれないのだ(よい面を見よう!)。


gccでライブラリを作っている。
最初は共有ライブラリにするつもりで、-fPIC、なんかつけていたのだが、やっぱり静的ライブラリにしようということで、オプションを外した。
arしてlibxx.aを作って、ちゃんと動いて、単体テストも結合テストもほぼ終わっていた。

が、さっきMakefileを見ると、-sharedが残っている!
うわー、こりゃいかんだろー。

ということで、外してビルドし直し、テストもやり直している。
が、ライブラリにバイナリ差分はあったのだけど、実行ファイルは-sharedがあろうとなかろうと差分がないのだ。

偶然そういうコードだったのか?と思ってgccのオプションを調べ直したら、-sharedってリンクオプションじゃないか!
静的ライブラリはarするだけでリンクしないから、リンクオプションに何が残っていても意味が無いのだ。
あぁぁぁぁ。。。

 

ライブラリを作り直した以上、実行ファイルが同じものであってもなくても、タイムスタンプ的に時間のずれがあると気持ちが悪いし、説明を求められるとなかなか苦しい。
あきらめて、最初からログを取り直している最中である。。。

ゴミ箱にファイルは残っているから戻せばよいのだけど、もう気持ちの問題だ。
幸い、放置系のテストが多いので、動かしておけばよいだけだし。
テストアプリに時間を掛けてよかった。。。

 

反省

使っているオプションかどうかくらいは確認しよう。


気になるのは、arした結果が違ったということだ。

差分はファイルの先頭だけだったので、きっとファイルヘッダ程度だろうとは思ったものの、案外こういうので手を抜いてしまうと失敗するというのを経験上知っている(そして、手を抜かなかった場合は、今回のようになんともない、ということが多い。。。)。

オブジェクトを残してarだけし直しても差分がある。
やはり、コンパイルしたオブジェクトには変化がなく、arしたときの差分だけということだ。
オブジェクトが同じだからチェックサムのようなものではなく、タイムスタンプ的なものだろう。

 

ar (UNIX) - Wikipedia

あー、ファイルヘッダの2項目目にタイムスタンプがあるな。
差分があるのも、確かにタイムスタンプフィールドの後半だけだ。
touchなどでファイルのタイムスタンプを変更しても、ar自体のタイムスタンプを書き換えないと「偽ってるだろう!」と思われかねないのか。

2016/09/17

[android]HCE-Fのソースを少しだけ見る

HCE-F記事のアクセス件数が多いと思ったら、紹介してもらっていた。
ありがたや。

Android 7.0のNFC HCE-Fの実装について – Qiita

 

HCE-F自体は、2年くらい前からSonyの人かFeliCaNetworksの人が発表していた。
Host Card Emulation、の略でHCEで、それのNFC-F版というかFeliCa版だから、HCE-F。

私が「HCE」という単語を見たのはAndroidが最初だが、私がやっていたカードエミュレーションもジャンルとしてはHCEになる。

カードエミュレーションは「エミュレーション」なので、NFCカード以外が行うことになる。
前回の話と重複するが、NFCチップはだいたい3つに分けられる。

  1. NFCカード用のチップ
  2. NFC R/W用のチップ
  3. NFCカードエミュレーション用のチップ

1番は、普通のカードに載るタイプだ。
nimocaやSuica、NTAG203なんかもそうで、カード側にしかならない。

2番は、R/Wに載るタイプだ。
PaSoRiのようなカードリーダで使うことになる。
基本的にR/Wでの用途になるのだけど、だいたいカードエミュレーションする命令も持っていて、カードになることができる。
私がやっていたのは、これだ。
ホスト側がないと、何もできない。

3番は、携帯電話に載るタイプだ。
PN544やモバイルFeliCaチップがそれにあたる。
基本的にカードエミュレーションするようにできていて、ホスト=本体側のCPUがなくても必要な機器に電源が入っていれば自律して動くことができる・・・と思う。

 

1番目はよく売られているし、2番目も売られているけど、3番目は一般にはほぼ出回らないと思っている。
下手に出回って悪用されると、カードのふりをすることができるから、ひどいことになるからだ。
まあ、2番目のでもカードエミュレーションできるから何かできるのかもしれないが、秘密の情報を保持するセキュアエレメントにアクセスできないのだと思う。

セキュアエレメントって、それこそNFCの信用に関する生命線なので、私のような一般人にはさっぱり何だかわからないのだ。
だから、ここら辺で書いているものも、私の推測が多い。
詳しい人が見たら「ふふん」と思われそうだけど、まあいいや。


紹介記事にあったソースファイルを見ると、nfa_dm_act.cの144行目あたりに差分がある。
「T3T」は、NFC Forumの「Type 3 Tag」の略で、まあFeliCaを指すと思ってもらえばよい。
LF_T3T_IDENTIFIERS_1~16とあり、これは「Listen Mode NFC-F Discovery Parameters」のことだ。
Listen Modeは、搬送波を生成しない側なので、カード側だ。
NCI v1.1ドキュメントでは、Page 59(PDFのp.69)の表に載っている。

0-1 : System Code
2-9 : NFCID2
10-17 : (optional) PMm

まあ、このコードは初期値の設定なので、あまり意味は無い。

 

実際に使う値は、たとえばnfa_dm_cfg.cの差分になるだろう。
ce_t3t.cの差分も同じようなものだ。
2つ数字が変わっているが、これはコメントによるとPAD0らしい。
PAD0は、いわゆるPMmのICコードに当たる。

PMmについては、Sonyの技術資料を読むとよい。
Sony Japan | FeliCa | 法人のお客様 | ダウンロード
この中の「FeliCa技術方式の各種コードについて」に書かれている(数字の意味は書かれていないが)。

PAD0という名称は、NFC ForumのDigitalProtocolで使われている。
こっちはこっちで定義がないのだが、0xFFFFはNFC-DEPするデバイス用として割り当てられている。

 

値くらいだったら見るのは簡単だと思ったけど、そもそも値はAPIから与えられるので、見ていってもあまり面白くないか。。。


NfcFCardEmulationクラスのAPIを見ると、NFCID2(IDm)とSystemコードは設定できそうだ。
Serviceコードもできるのかな?
あるいは、そこから自分で実装するのか。

Systemコードはドライブに、Serviceコードはフォルダに相当する。
Sonyの技術資料にもそういう説明があったような気がするが、見つけられなかった。

だいたいのFeliCaではSystemコードが0xFE00がデフォルトになっているけど、Suicaなどのサイバネ系は0x0003を使っている。
ポーリングするコマンド(NFC ForumのDigitalProtocolでいう、SENSF_REQ)でもSystemコードを指定するが、ワイルドカードの0xFFFFを指定するとデフォルトのSystemコードが反応する。
Suica側を見たかったら、Systemコードをちゃんと指定しないと出てこない。
まあ、これはFeliCa LiteをNDEF対応したときも同じ話だ。

 

以前、HCEで訳もわからず作ったときは、HostApduServiceクラスをextensしたクラスにprocessCommandApdu()の中身を実装した。
それに相当するのは、HostNfcFServiceクラスだろう。

processCommandApdu()に相当するのはprocessNfcFPacket()か。
PCD側に値を返すときはreturnで返すところも同じだ。

APDUの場合は、引数のデータはCLAから入っていた。
NFC-Fにはそういう形式はないので、サブコマンドコード(Check=0x06、Update=0x08など)から渡されて、返す値もサブレスポンスコード(Check Res=0x07、Update Res=0x09)などとなるのだろうか。

だったら、NDEFくらいだったら簡単そうだ。


ただ。。。うちには試せる環境が無いので、確かめられない。

これをうまいこと使えて、しかもNCIがデータをチェックせずに送受信できるのであれば、実在しないFeliCaコマンドを作ることができるかもしれない。
どうなんだろう、さすがにチップ側でチェックするのかなぁ。
くぅ、だんだん試したくなってきた。。。

2016/09/16

載ってるか載ってないかよくわからん

iPhone7を分解する記事があったので、読んでいた。

https://www.ifixit.com/Teardown/iPhone+7+Plus+Teardown/67384

型番はA1785ということで、FeliCa対応している端末のようだった。

Step 15に、NXPのNFCコントローラが出てきている。
しかし、モバイルFeliCaチップは記事には出てこなかった。

うーん、これはどう読むとよいのだろうか。。。

  • 紹介されていないチップの中に、モバイルFeliCaチップがある
  • NXPのチップしか載っていない
  • 全然違う技を使っている

いくらFeliCaチップといえども、セキュアエレメントがなければメモリを持っていないはずだ。
iPhone6のNFCは、セキュアエレメントの使い方が通常と違うという記事を読んだ気がするのだけど、もう昔のことなので忘れてしまった。

NXPのチップしかなくて、FeliCaのセキュアエレメントがないとなると、ソフトでカードエミュレーションするくらいしか思いつかない。
カードエミュレーションだと、ホスト側ががんばらないといけないので、けっこう電力を使うはずだ。
(モバイルFeliCaチップは、チップがカードエミュレーションするので、FeliCaチップ周りにだけ電力があれば事足りる。)

 

さあ、どうなんだろうね?
日経テクノロジーさんも分解するようだから、そっちを読んだ方がわかるかも。
しかし、こっちは時間がかかりそうだ。
http://techon.nikkeibp.co.jp/atcl/feature/15/090900039/091600001/

[nfc]HCE-Fに対応している端末はどうやって調べられるのか。。

HCE-Fが気になっているが、適当に端末を買っても対応していなかったら目も当てられない。
買うかどうかは別として、対応している端末の調べ方はあるのだろうか?

 

まず、モバイルFeliCaチップが載っているものは対応しないんじゃなかろうか。
必要ないということで。
しかし、もしHCE-Fでしか対応しない企業が出てきたら、そうも言っていられないのかもしれん。

何が分けるかというと、NCIだと思う。
今はダウンロードできなくなったけど、NFC Forumの規格としてNCIというものがある。
ドライバはこれに対応しておけば、チップ側がNCIに対応していれば交換しやすい、というようなものだったと思う。

NCIの中に、Type3 TagだけNFCEEの規格がある。
まあ、他はISO-DEPなどを使っているから、FeliCa系だけは名前がないからそうしただけかもしれんが。

image

NFCEEは、Secure Elementみたいなアプリケーションを意味している(と思っている)。
NFC Execution Environmentの略だ。

NCIのドキュメントでは「T3」という略称でType3のことがよく出てくる。
ただ、Mandatoryではなかったような記憶があるのだ。
探しているが、出てこない。。。

 

なので、たぶんHCE-Fに対応するなら、NCIのこの辺に対応しているということになるんじゃなかろうか。
R/W機能はNFC ForumでA,B,Fと必須にしているけど、カードエミュレーション機能についてはオプショナルだから、ドライバが対応しなくても不思議ではない。

あー、でもホストがエミュレーションするんだから、NCIで対応しなくてもよいということになるのか?
この辺はよくわからんな。。。

 

あと、HCE-FはAndroid6から実装されていたという情報もあった。
でもNfcFCardEmulationはAPI24からだなぁ。
FEATURE_NFC_HOST_CARD_EMULATION_NFCFもAPI24だし。
ともかく、うちのNexus5では確認できないということはわかった。

 

最終的にSIMに移行するというステップだったと思うけど、そっちはどうなってるんでしょうな。
SIMに載ればFeliCaチップを載せなくて済むので端末の自由はきくけど、速度遅くなるし国内だと使われ無さそうな気がする。
まあ、私の予想はいつも当たらないからなぁ。

ちなみに、2年前にNFCが載ったときはHCE-Fだったらいけるかなー、と思ったものだ。
ほら、予想が外れてる。。
hiro99ma blog: もごもご

2016/09/15

[c/c++]私のC言語 (17) - printfデバッグ

もう、C言語と関係なくなってきたが、気にしないでおくれ。。。

組み込み開発で、新しい開発環境が提供されたとする。
マイコン自体初めてだったり、ARMだけどメーカーが初めてだったり、コンパイル環境が初めてだったりするのは珍しくないだろう。
ドキュメントを読みながら環境を作って、ビルドして、何だかわからないけどサンプルも動いた!

その次にどこからやっていこうか?となる。
マイコンのことを調べたり、OSが載っていたらそれを調べたりするのだけど、私はサンプルの動きを追うことが多い。
せっかく動いたのだから、もう少し見ておこうか、というわけだ。

このとき、ブレークポイントで止めながら調べるのもよいだろうけど、無線を使う場合だと止められなかったり、止めると意味が無くなったりするので、動かしながらトレースしたいと思う。
そうなると、高級なデバッガだとトレース機能がついているものもあるだろうが、手軽なのはデバッグ出力を追加することだと思う。

printfデバッグ、と呼ばれることもある、よくある方法だ。
ソースを変更することになるので、副作用が発生する場合もあるのだが、容易なのでしばしば使う。


printf、といっても、別にprintfじゃなくてもよい。
組み込み環境では標準出力がない場合も多いので、どこかに何かを出力する、くらいのイメージだ。

一番楽なのは、UARTだと思う。
UARTに文字列を取得して、電圧変換してパソコンのシリアルポートとつなげれば、TeraTermなどで出力を目で見ることができる。
sprintfなんかが使えるなら、変数の値を見るのも楽にできて、お手軽だ。

 

ただ、UARTは他の用途で使われて、空いていないこともある。
そうなったときにどうするか、というのが、あまり私は手段を持っていない。

I2CはSPIが同じシリアル系列でよいのだけど、それをどうやって見える形にするかが悩ましい。
UARTに変換するチップもあるから持っていればよいのだが、今は手持ちがない。
単発でよければロジアナで足をつかむという手もあるが、トレースしてみたいときだとちょっと足りない。
それに、最近は足がつかめないマイコンも多いので、そもそも出力できないということもあろう。

そういう点で、JTAGデバッガから直接出力できる場合はありがたい。
SEGGERのRTTみたいな機能だ。
Semi Hostingは同様の機能かと思っていたけど、今使ってるやつは出力先をUARTにしか割り振れないようなことが書かれていて、意味が無い。。

 

ともかく、何かしらトレースする手段を持っておくと、デバッグ効率が上がることもあるのでよいのではなかろうか。

2016/09/14

[nfc]HCE-FはAndroid7から使える

この記事を見るまで、HCE-FがAndroid7から搭載されたことをまったく知らなかった。
第772回:HCE-Fとは - ケータイ Watch

 

APIはこれだろう。
NfcFCardEmulation | Android Developers

  • getNfcidForService()
  • getSystemCodeForService()
  • registerSystemCodeForService()
  • setNfcid2ForService()
  • unregisterSystemCodeForService()

名前がくどいな。。
まあ、CardEmulationクラスも同じような名前を付けているから、ルールに沿っただけか。

 

HCE-Fをサポートする機種でしか使えないのだが、どこで分かれるのだろう?

まず、NFCが載っていて、NfcFをサポートしているのは必須だろう。
NFC Forumとしては、A,B,FのRead/Writeについてはサポートしないといかんのだが、Androidにそこまでの義理はないから、A,BはあってFがないという可能性もなくはないだろう。
ただ、NFCチップはどれも対応していそうな気がするので、ドライバ次第なのか。

NFCチップも、Reader/Writer系のチップと、Emulation系のチップがあるはずだ。
RC-S956やPN532なんかは前者で、PN65NやPN544は後者だ。
Reader/Writer系のチップは買いやすいのだが、Emualtor系のチップは普通の人は買えないんじゃなかろうか。
携帯電話に載せるのはEmulator系のチップになるので、私もよく知らない。

FeliCa Liteや、FeliCaでも暗号化されていないところを読み書きする分には、Read without EncryptionやWrite without Encryptionを使う。
そうじゃない場合は、ReadとWriteを使う。
このReadとWrite、あとは認証系のコマンドもあると思うが、この辺りが使えるかどうかで分かれるんじゃなかろうか。
コマンドの詳細は、18092はどうだったか忘れたが、JISには載ってたと思う。

このReadやWriteを使わないと、無線の間が暗号化されないのだ。
暗号化されないと、データを読めば何をしているのかわかってしまうから、安全でない。
だから、HCE-Fをやるとなれば、それもサポートしないといかんのじゃなかろうかね。

 

試してみたいのだが、うちのNexus5はAndroid7が載らないのだ。。
XDAでビルドしているという話は聞くのだが、それでHCE-Fがサポートされるのかどうかとなると、されないような気がするのよね。。。

2016/09/13

[win10]Facebookアプリなどがうまく立ち上がらない(未解決)

ネタはためておけばよいものを。。。

ときどき、FacebookのMessengerで連絡が来ることがある。
以前はFacebookなんて週に1回ログインすれば多い方だったのだが、最近は1日に1回以上も確認しているので、遅くて怒られるようなことはない。

が、ログインするのは面倒といえば面倒だ。
通知してもらった方が楽そうなので、Windows10でアプリをインストールした。
ストアアプリのMessengerで、ちゃんとFacebookがリリースしているものだ。

インストールも成功するのだが、起動すると起動画面の青いMessengerがばーんと出てきた後、ずーっとそのままになって、勝手に落ちるのだ。
試しにFacebookアプリもインストールしたが、同じ。

管理ツールのイベントビューアで「Windowsログ > Application」を見ると、

障害が発生しているアプリケーション名: WinUAPEntry.exe

ということで、障害が発生して立ち上がっていないことがわかった。

 

じゃあ解決方法もわかるだろうと思ったのだが、これが出てこない。
現象が出ている人はいるのだが、解決したような気配が見えないのだ。
一番最後に「I installed Messenger from FB and the FB app works just fine now.」とあるけど、そもそも立ち上がらないしねぇ。

思い出すのは、Excelのときだ。
セキュリティ設定のためにあれこれ切ったけど、それが影響しているのでは?ということだ。
あれは、Spybot Anti-Beaconアプリでやったので、戻してみたけど同じだった。

 

まあ、このPCじゃなくてもう1台のPCでも動かなかったし、Facebook関係だけじゃなくて、標準のメーラもうまく動いてくれないから、いつもやっている設定とかかもしれん。
しばらくはブラウザでいいや。


[c/c++]私のC言語(16) - 文字コードと改行コード

いかん、ネタが切れてきた。。。
今回は、文字コードと改行コードについて書く。

 

日本語でソースファイルを書くと、だいたいこの辺を考慮することになるんじゃなかろうか。

  • 文字コード
  • 改行コード
  • タブの方式

改行コードとタブは日本語と関係ないが、まあいいや。

 

私は、今はこういう書き方をすることが多い。

  • 文字コード : UTF-8
  • 改行コード : LF
  • タブの方式 : スペース4つ

Windowsがメイン環境なので、デフォルトではShift-JISとCR/LFになることが多いのだけど、日本語で出力することが少ないのと、githubなんかに置くとUTF-8じゃないと化けそうだから、UTF-8にしている。

ただ、WindowsだとBOMありのUTF-8にされることもあるので気が抜けない。。。
notepadで、そのまま保存するとShift-JIS、UTF-8で保存するとBOMありになった。

そうなってくると面倒なので、じゃあ改行コードもLFにして、UNIX風というかLinux風というかのソースファイルにしておけば間違いは少なかろう、ということで、そうしている。

 

これも「ただ」がつくのだが、Windowsでgitを使うと改行コードが変換されることがあり、これはこれで気が抜けない。
Linuxで編集したり、Samba経由でWindows使ったり、gitをLinuxで使ったりWindowsで使ったり、ツールの設定をチームで決めていなかったりしたせいで、けっこうひどい目にあった。。。

チーム開発をするときには、ツールの設定も危険なところについては統一するべきだった、という手痛い教訓だ。

 

その昔は、あまり気にしていなかった。
日本語はコメントのところしかないから、だいたいうまくいっていたのだ。

が、ある日よくわからないコンパイルエラーが発生した。
どう見てもおかしいところがないのだが、なぜかエラー。
さんざんやって、もうわからん、とコメントを消したら通った。

そこは「//」コメントで「○○機能」と書いているだけだった。
そう、機能の「能」はShift-JISで0x945C。
後半の0x5Cは、文字にすると「\」。
そう、コンパイラがShift-JISを判断してくれず、次の行に継続する扱いにしていたのだ。
もしCコメント形式だったら回避できたのだろうが、//で行末に0x5Cが来たため、そう見なされたのだろう。

当時はまだUTF-8は標準だったから、日本語EUCに変換する習慣を付けたり、ソースファイルを一括置換するツールを探したりと、とにかく回避するよう心がけた。

失敗すると、ノウハウがたまるから、大ごとでなければよいのだよ。

2016/09/12

[nrf52]Secure DFU Bootloaderを試す (1)

nRF52とは直接関係ないのだが、nRF5 SDK v12を試せるデバイスがうちにはnRF52832しかない。
今回は、Secure DFU bootloaderを調べよう。


micro-ecc

楕円曲線暗号ライブラリのmicro-eccをgithubから持ってくる。
cloneするフォルダも決まっているので、やり方はここら辺を読んでおくれ。

そして、nRF5_SDK_12.0.0_12f24da\external\micro-ecc\nrf52_armgcc\armgcc\でmakeする。
そうしたら、同じフォルダにmicro_ecc_lib_nrf52.aができる。

 

ビルド

nRF5_SDK_12.0.0_12f24da\examples\dfu\bootloader_secure\pca10040_debug\armgcc\でmakeする。
これはdebug版のフォルダなので、好きにしておくれ。
ビルドすると_buildの下に、えらく大きいbinファイルと、小さいhexファイルなどができる。

これで、ブートローダができた。


次は、DFUで送るファイルを作る。
説明ではInitパケットのことが書いてあるのだけど、後回しにしよう。

> nrfutil pkg generate [option] zipファイル名

optionでは、DFUするファイルも指定するが、--key-fileでPEM形式の秘密鍵を指定できるようになっている。
signとあるし、DFUするファイルを暗号化するのではなく、DFUファイルがいじられてませんよ、の署名として使うということか。

InitパケットのところにSignature typeがあるが、これがPEMで指定するのと一致しないとダメだろう。
このサンプルではECDSA_P256_SHA256だそうだ。

たぶん公開鍵はdfu_public_key.cとしてブートローダに埋め込むことになっている。
そして、検索した範囲ではPEMファイルがないので、自分ではこの公開鍵で使えるzipファイルを作ることはできないだろう。

 

DFUするファイルはzipになるだけだから、解凍すればHEXファイルが見えるだろう(binになるかも)。
DFUファイル自体を暗号化して、どういうことをやっているのか解析されないようにもできるとよいのだけど、さすがにそれはnRF側の負荷が重たいのか。
AESだったら、nRFも持っているからやりやすいかもしれんが、実現するにはいろいろ作らないとダメだよねぇ。


と、調査だけで今回は終わってしまった。
試すのは次回だ。

2016/09/11

[nrf52]UARTのEasyDMAとはなんぞや

nRF52832には、EasyDMAという機構というかユニットがある。
DMAは、Direct Memory Accessで、CPUを介さずにメモリをアクセスするユニットだと思えばよいだろう。

だいたい、DMAを使うときにはこういうデータをセットする。

  • 転送元のアドレス
  • 転送元アドレスの進め方
  • 転送先のアドレス
  • 転送先アドレスの進め方
  • バスの扱い方

最近使っていないからちょっとあやしいが、だいたいこんなもんだろう。

メモリからメモリへの転送であれば、アドレスはアクセスごとに進めるなり戻るなりしたいだろうけど、片方がレジスタであれば同じアドレスをアクセスし続けたいはずだ。

また、DMAユニットがメモリのバスを使い続けると、そのバスを使いたい人は空くまで待たないといけない。
バースト転送だとそんな感じだけど、アクセスごとにバスを空ける方式もあったと思う。

転送が終わったら割込みが上がるか、転送完了フラグが立つか、というパターンであろう。


nRF52832のProduct Specでは、2ページ程度で説明されている。
レジスタ仕様などなく、こんな接続ですよ、というくらいだ。

EasyDMAは、メモリ-メモリ間の転送はできず、RAMといくつかの周辺機器間に限定しているようだ。
その分、使い方が簡単になっているのが「Easy」の意味か。

そして、周辺機器の相手は「メモリ」ではなく「RAM」なのだ。
たとえば、UARTドライバの送信nrf_drv_uart_tx()では、EasyDMAを使うルートにこういうコメントがある。

// EasyDMA requires that transfer buffers are placed in DataRAM,
// signal error if the are not.

渡されたアドレスがデータRAMかどうかをチェックして、違う場合はエラーにしているのだ。
チェックするマクロは、こうなっている。

#define IS_EASY_DMA_RAM_ADDRESS(addr) (((uint32_t)addr & 0xFFFF0000) == 0x20000000)

送信だからconstなデータを送ることもあるだろうけど、EasyDMAを使いたいのであれば一度RAMに移して、そのアドレスから送信してやらないといかんということだ。

 

EasyDMAがある場合のUART構成は、こうなっている。
Product Specでは「UARTE」となっている。

image

nRF51と同じ構成のUARTもある。

image

外から見ると、STARTRX, STOPRXや、PSELRXD, PSELTXDは同じなのだけど、それが内部でどうつながっているかが違うようだ。

 

app_uart_put()を使うと送信サイズが1なので、あまりEasyDMAを使ってもありがたみがなさそうな気がする。
だが、転送データは最終的に構造体に入れられてnrf_drv_uartに渡されるので、アドレスは心配しなくてよさそうだ。


 

ドライバのソースは、EasyDMAなのかどうかを、CODE_FOR_UARTE()とCODE_FOR_UART()で分けている。
分けているのだが、パターンとして

  • UARTのみ
  • UARTEのみ
  • UARTEとUART両方

を許容しているようだ。
EasyDMAだけだと、RAMに置けないような大きいデータをやりとりできなくなってしまうので、両方使えるようにもしてあるのだろうか。

 

nRF51でUARTの送信バイト間がやたらと空いてしまうことが有り、おそらくUART送信とSoftDeviceの処理が重なり、SoftDeviceが優先されたためだろうと思っている。
バイト間タイムアウトがあるデバイスを使っていたので問題になったけど、DMAもなく上手に回避できなかったのだ。

2016/09/08

[c/c++]私のC言語 (15) - 静的解析ツール

自分でコードを書いていると、レビューを求めたいときがある。
しかし、誰もいないので、ツールにお願いしたい。
そういうわけで、無料で使えそうな静的解析ツールを探してみよう。

昨年の調査は、ここだ。
http://hiro99ma.blogspot.com/2015/11/cc.html


静的解析ツール AdLint (アドリント)

いきなりだが、AdLintは今年の1月に提供が終了したそうだ。。。


Cppcheck - A tool for static C/C++ code analysis

これは、私が今使っているツールだ。
設定が簡単なのだけど、もうちょっと指摘してほしい気がする。


Infer | A static analyzer for mobile apps | Infer

昨年は、Windowsでサポートしていないのと、cygwinで試そうとして失敗したので、そのままにしていた。
今も、Windowsをサポートしていないのは同じだった。。。
はっ、今ならBash on Ubuntuがある!

依存関係をUbuntu14.04のをまねして(かなり時間がかかる)、wgetで0.9.2を取ってきて、解凍してスクリプト実行(これもかなりかかる)。
よくわからんが、スクリプトがうまく行かないようだったので、コンソールに出ていた「opam depext conf-pkg-config.1.0」を実行し、それでも何か言っているので、apt-get install clang-3.5した(時間かかる)。

だめだー。
「C compiler cannot create executables」が消えん。
config.logを見ると、単にコンパイルできていないだけのようだが。。

「CXXABI_1.3.8が無い」「GLIBCXX_3.4.20が無い」がずらずら出ているようだ。
stringsで/usr/lib/x86_64-linux-gnu/libstdc++.so.6を見ると、「CXXABI_1.3.7」「GLIBCXX_3.4.19」と、一歩手前のようだ。
プレビルドされているコンパイラが、新しいってことかな?

じゃあ、gitから直接取ってきて全部ビルドするか、とやってみたが、cmakeが古いということでppaで何か追加したところまではよかったが、バージョンがまだ古いらしい。
しかたなく、cmakeのソースからビルドし直す。。。。

えい、ここは、古いinferで試してやれ。
0.3.0くらいだったら1年前だし。。。ああ、コンパイル手順自体違う。。。

 

ここで無理をするのはやめよう。
Xubuntu16.04にはrelease 0.9.2があっさりインストールできた。

infer -- clang -c xxx.c

こんな感じでコマンドを打つと、コンパイル時のマクロ定義などをせずにチェックして、結果も出た。
cppcheckで通ったコードだったためか、エラーも何もない。
カレントディレクトリにinfer-out/というディレクトリができるが、bugs.txtくらいしかわからん。
procs.csvは関数ごとの何かを調べているようだが、ステップ数でも複雑度でもなさそう。
うーん。。。

helpを載せておこう。

$ infer --help
Infer version v0.9.2
Copyright 2009 - present Facebook. All Rights Reserved.
  
  Toplevel options

  --analyzer | -a { capture | compile | infer | eradicate | checkers | tracing | crashcontext | linters }
                   Specify which analyzer to run (only one at a time is
                   supported):
                   - infer, eradicate, checkers: run the specified analysis
                   - capture: run capture phase only (no analysis)
                   - compile: run compilation command without interfering (Java
                   only)
                   - crashcontext, tracing: experimental (see --crashcontext and
                   --tracing)
                   - linters: run linters based on the ast only (Objective-C and
                   Objective-C++ only)
  --<analyzer>-blacklist-files-containing <string>
                   blacklist files containing the specified string for the given
                   analyzer (see --analyzer for valid values)
  --<analyzer>-blacklist-path-regex <path regex>
                   blacklist the analysis of files whose relative path matches
                   the specified OCaml-style regex
                   (to whitelist: --<analyzer>-whitelist-path-regex)
  --<analyzer>-suppress-errors <error name>
                   do not report a type of errors
  --buck-blacklist <regex>
                   Skip analysis of files matched by the specified regular
                   expression (Buck flavors only)
  --changed-files-index <file>
                   Specify the file containing the list of files from which
                   reactive analysis should start
  --continue       Activates: Continue the capture for the reactive analysis,
                   increasing the changed files/procedures. (If a procedure was
                   changed beforehand, keep the changed marking.) (Conversely:
                   --no-continue)
  --disable-checks <error name>
                   Do not show reports coming from this type of errors
  --fail-on-issue  Activates: Exit with error code 2 if Infer found something to
                   report (Conversely: --no-fail-on-issue)
  --no-filtering | -nf
                   Deactivates: Do not show the results from experimental checks
                   (note: some of them may contain many false alarms)
                   (Conversely: --filtering | -nf)
  --flavors        Activates: Buck integration using Buck flavors (clang only),
                   eg `infer --flavors -- buck build //foo:bar#infer`
                   (Conversely: --no-flavors)
  --inferconfig-home <dir>
                   Path to the .inferconfig file
  --jobs | -j <int>
                   Run the specified number of analysis jobs simultaneously
                   (default: 3)
  --load-average | -l <float>
                   Do not start new parallel jobs if the load average is greater
                   than that specified (Buck and make only)
  --merge          Activates: Merge the captured results directories specified
                   in the dependency file (Buck flavors only) (Conversely:
                   --no-merge)
  --pmd-xml        Activates: Output issues in (PMD) XML format (Conversely:
                   --no-pmd-xml)
  --no-progress-bar | -npb
                   Deactivates: Show a progress bar (Conversely: --progress-bar
                   | -npb)
  --project-root | -pr <dir>
                   Specify the root directory of the project (default:
                   /media/sf_work/libicdrvlic)
  --Xbuck          Pass values as command-line arguments to invocations of `buck
                   build` (Buck flavors only)
  --xcode-developer-dir <XCODE_DEVELOPER_DIR>
                   Specify the path to Xcode developer directory (Buck flavors
                   only)
  --               Stop argument processing, use remaining arguments as a build
                   command
  --help | -h      Display this list of options
  --help-full      Display the full list of options, including internal and
                   experimental options
  
  Analysis (backend) options

  --debug | -g     Activates: Debug mode (also sets --print-types and
                   --write-dotty) (Conversely: --no-debug | -ng)
  --debug-exceptions
                   Activates: Generate lightweight debugging information: just
                   print the internal exceptions during analysis (Conversely:
                   --no-debug-exceptions)
  --results-dir | -o <dir>
                   Write results and internal files in the specified directory
                   (default: /media/sf_work/libicdrvlic/infer-out)
  --unsafe-malloc  Activates: Assume that malloc(3) never returns null.
                   (Conversely: --no-unsafe-malloc)
  --version        Activates: Print version information and exit (Conversely:
                   --no-version)
  --version-json   Activates: Print version json formatted (Conversely:
                   --no-version-json)
  
  Clang frontend options

  --cxx            Activates: Analyze C++ methods, still experimental
                   (Conversely: --no-cxx)
  --headers | -hd  Activates: Analyze code in header files (Conversely:
                   --no-headers | -nhd)
  --ml-buckets <,-separated sequence>
                   Specify the memory leak buckets to be checked in
                   Objective-C/C++:
                   - 'cf' checks leaks from Core Foundation,
                   - 'arc' from code compiled in ARC mode,
                   - 'narc' from code not compiled in ARC mode,
                   - 'cpp' from C++ code (default: cf)
  --skip-clang-analysis-in-path <path prefix>
                   Ignore files whose path matches the given prefix
  --skip-translation-headers <path prefix>
                   Ignore headers whose path matches the given prefix
  
  Java frontend options

  --absolute-paths
                   Activates: Report errors using absolute paths (Conversely:
                   --no-absolute-paths)
  --android-harness
                   Activates: (Experimental) Create harness to detect issues
                   involving the Android lifecycle (Conversely:
                   --no-android-harness)
  --modeled-expensive <json>
                   Matcher or list of matchers for methods that should be
                   considered expensive by the performance critical checker.
                   (default: [])
  --never-returning-null <json>
                   Matcher or list of matchers for functions that never return
                   `null`. (default: [])
  --skip-translation <json>
                   Matcher or list of matchers for names of files that should be
                   analyzed at all. (default: [])

ああ、マクロ指定が無い、とかじゃなくて、--より後ろにコンパイルするコマンドを書くというやりかたなのだな。
clangじゃなくてgccでもよいのだろうし、-Dでオプションを並べてもよいのだろう。
なんとなく、clangの方がチェックしてくれそうな気がする。

エラーが出なくて寂しいが、ちゃんとエラーが出るようにしておけば出そうだから、よしとしよう。

[c/c++]私のC言語 (14) - const volatileなんてものがあるのか

だんだん「私の」が何を意味しているのかわからなくなりつつあるが、深くは考えまい。
コーディング作法ガイドをまだ読んでいるが、いろいろ知らないことが出てくる。

 

今回は、p.86に出ていた「const volatile」。
プログラムからは参照しかせず、別の実行単位から変更されるメモリのときに使うとよい、と書かれている。
別の実行単位というのは、スレッドとかタスクとかだろうか。

その場合、別の実行単位と同じメモリを参照しているはずだから、片方はexternになるんじゃなかろうか?
本体はconst無しで、externにconst有り、というのは警告されないんだろうか。
スレッドなどを作るのが面倒なので、ソースファイルを2つに分割して試したが、警告は出なかった。
もちろん、ちゃんと動く。
const有りの方で代入すると、ちゃんとコンパイルエラーになる。
ふーん。



さすがに逆はダメよね?
本体がconst有りで、externがconst無し、というパターンだ。
・・・警告が出ないし、ちゃんと動く。
ふーん。



片方にvolatile有り、もう片方にvolatile無しは?
いいんだ。。。
constもvolatileも型修飾子だから、飾り以上の意味を持たないと言うことか。



では、volatileは抜きにして、本体をconstを付けたint変数を、片方にextern intで、externした方で書き換えた。
いける。

ではでは、const intなのは同じとして、初期値を付けたらどうなる?
あ、警告などは出ずにビルドできるのだが、Segmentation Faultが起きた。。。
初期値があるとデータをROM側に持つけど、初期値がない場合は違うんだ。

cygwinのGCCだから、他のコンパイラだと違うかもしれんが、微妙なことはしたらいかんということだ。
リンクではじくしかないけど、Cだと名前だけじゃわからないからリンクしてしまうのか。
C++だと、そもそもconstのくせに初期値無しにするんじゃねえ(-fpermissive)と言われてコンパイルエラーになるし、初期値を入れてもリンクでちゃんと失敗してくれるな。


ちなみにconst定数は、CとC++で扱いが違うので注意がいるかも。
C++だとリンクが内部リンケージになるので、ヘッダファイルに置いても多重定義にならなくなるのだ(externしなければ)。
だから、C++ではマクロじゃなくてconst定数で書いてヘッダに置くこともできそうだけど、紛らわしいからやらない方がよいかもね。
やるなら、各ソースでstaticにするか、C++ならclassの中でstatic const intなどにするかな。
「プログラミング言語C++ 第3版」 p.246を読み返したが、constとtypedefがそうらしい。

前のプロジェクトで、ヘッダにconst変数を書いていて、それをstaticにしてるファイルがあったのを思い出した。
管轄外のソースだったので放置したけど、書いた人も放置した人も、お互い罪深いよねぇ。。。

[nfc]iPhoneに載るのだ

iPhone7/Plus 7/Watch 2にモバイルFeliCaチップが搭載されるらしい。

FeliCa NFC technology confirmed for Apple Pay in Japan • NFC World

私の予想は外れたが、まあよかろう。


海外のNFCチップでも、NFC-Fの通信はできる。
しかし、Secure Elementの操作まではできないから、載るならモバイルFeliCaチップしかないはずだ。
こんなのかな?
お知らせ|FeliCa Networks

 

このFeliCaチップが載るのは日本向けの端末だけなのだろうか?
以前のFeliCaチップは暗号化が3DESだったけど、今はAESに対応しているし、NFC Forum規格に対応しているだろうからNFC-A/Bもアクセスできるだろうから、iPhone6で使っていたチップと機能的には交換できるとは思う。
両方載せるのは無駄な気もするけど、FeliCaが使えるAndroid端末は似たようなもんじゃなかったっけ。。。

観光や出張で来る人もいるだろうし、東京でオリンピックがあるらしいから、載っていても無駄になるということはなかろう。
なにより、作り分ける方が面倒じゃないか?という気がする。

「bringing to Japan」といっているので、日本に持ってくれば使えますよ、という意味なのかな。
あー、でもこっちには、日本市場向けのみと書かれている。
http://toyokeizai.net/articles/-/135068

となると、日本向け端末とそれ以外ということになるのか。
日本向けの場合、あれこれやっても海外でApple Payが使えなくなったりするのだろうか。
リージョンコードでどうのこうのらしいけど、よくわからん。
まあ、それだったら、日本で端末だけ購入するような転売は減るだろうし、逆の転売も減るとは思う。

 

また、Apple Payとして使えるところも興味深い。
登録の仕方を見ると、Suicaを持っている人はかざして情報を読むようだ。
クレジットカードの場合は写真を撮影していたような記事を見た気がするのだが、R/W機能も使えるんだな。

モバイルSuicaのよいところは、モバイル決済とモバイルチャージだと思う。
私はあまりチャージをしに行きたくないので、夜に家で思い出してチャージする、というのがうらやましい。
福岡でもモバイルSuicaは使えるけど、チャージできるのがviewカードとか一部の銀行以外は有料だったので、それならnimocaのままでいいやん、となるのだ。
だから、Apple Payに対応したクレジットカードからなら無料でチャージできる、だったら、ちょっとうらやましいかも。


ただ、FeliCaが使えるにせよ使えないにせよ、APIとしては制御できないと思うから、あまり興味は無いのであった。。。

RC-S390は、iPhone7以降はあまり使うところがなくなってしまうのだろうか?
まあ、新しい機種に全員が乗り換えるわけでもなかろうし、Edyなんかは新しくても使えないだろうから、それはそれでよいのかな。

 

日本だけFeliCa搭載、だと、FeliCaが世界展開したというわけではないということか。
こうなったことで、返って「もういいや」になってしまわないか心配だ。

2016/09/07

[c/c++]私のC言語 (13) - ファイル名引数はconstにしておくれ

open()やfopen()のファイル名は、const char*だ。
しかし、お仕事でやっていると、ときどきchar*にしている自作関数に出会うのだ。
そういうのに限って、みんなが使うような関数になっている。。。
中身を書き換えないポインタ引数はconstにしておくれ、というのが主張なのだけど、ファイル名以外ではまあまあconstにしてあるように思える。
つまり、ファイル名のときだけconstがない場合が多いような気がするのだ。
まあ、たまたまそういう会社に数社当たっただけかもしれんがね。

const無しのポインタ変数にconstのポインタ変数を引数で渡すと、だいたいコンパイルエラーになる。
回避するには、こんな手段くらいしか思いつかない。
  • constのデータをRAMにコピーして引数に渡す
  • constを外した形でキャストして引数に渡す
後者は、やりたくない。
やりたくないのだが、わざわざファイル名のためだけにRAMを確保するのも腹が立つし。
そもそも、ファイル名を書き換えるとしたらどういう場合だ?
あり得んだろう!と、いろいろ思考をごまかして、コードを確認して書き換えていなかったら、ときどきキャストで逃げている。

ファイル名なんて固定で持っておくことも多いと思う。
もし、
char fname[] = "/foo/bar/hogehoge.conf";
なんて書いたら、
  • 初期値"/foo/bar/hogehoge.conf"をROMで持つ
  • fnameのスタック確保
  • fnameの初期化
が行われるではないか。
constで持っておけば、ROMのサイズだけで済むのに。。。

まあ、RAMの方がFLASHよりアクセス速いよねー、と言われるとどうしようもないのだが、少なくともファイル名は関係ないよな、と思う。

[c/c++]私のC言語 (12) - includeガード

ヘッダファイルは、2回以上読込まれないようにするために、いわゆるincludeガードをすると思う。
私の名前付けルールは、こんな感じだ。

#ifndef MY_HEADER_H__
#define MY_HEADER_H__

~~

#endif //MY_HEADER_H__

 

昔は、マクロ名の前にアンダーラインを置いていた。
たぶん、読んだ本だか参考にしたコードがそうなっていたからだろう。
C言語規格上、それはよろしくないというのを知ってからは、使わないようになった。

コーディング作法ガイドでもp.75にその話が書かれていた。
マクロ名だけ気にしていたのだが、変数名や関数名もそうなのだな。
まあ、2回使われているなら衝突してビルド時に気付きそうな気もするが、使っただけで動作が変わるマクロとかがあるとやっかいだから、使わないに越したことはないだろう。

 

最近知ったのだが、gccでもincludeガードの#pragma onceが使えるようだった。

#pragma once

VC++だけかと思っていたが、けっこうあるんだな。。。
gccも3.4からってことは、ずいぶん前から使えたんだ。

たまにやってしまうのが、ヘッダファイルをコピーして中身を書き換えるのだが、ガード下マクロ名を変更し忘れる、というものだ。
includeが重なっていなければうまくいくけど、順番によってもう片方が無効になってしまうので、しばし理由がわからずに悩んでしまうのだ。

でもまあ、pragmaだから、こういうルールはプロジェクトで統一した方が良かろうね。

2016/09/06

[nfc]公開鍵は証明書の一部だった

先日、マイナンバーカードから公開鍵を読み出した。
使い道はないものかと、暗号の本「暗号技術入門」を読んでいたところ、証明書という項目が出てきた。

カードから読み取ったのは、たぶん公開鍵だとは思うのだが、それは本当に私の公開鍵だろうか?
それをどうやって確認するのかというと、もうカードだけで閉じた話ではなく、その公開鍵を発行したところや、発行したところが本当にそうか、というようなものを確認することになるようだ。

本では「認証局トレント」という機関があり、相手は公開鍵を私から取得するのではなく、認証局トレントから取得するようになっていた。
まあ、私が本当に私かどうかわからないし、送ったものがそうなのかわからないからな。

このときに取得するのは、公開鍵だけじゃなくて、それを「認証局トレントが発行した」というデジタル署名がひっついた、公開鍵証明書という形でもらうそうだ。
こういった公開鍵の運用を行うしくみがPKI(公開鍵基盤)で、その日本版だからJPKIなのだろう。
細かいしくみや流れは、本を読むなどしてほしい。

 

では、私のカードにも、その証明書が入っているはずではないか?
そういえばJPKIからダウンロードした仕様書も、公開鍵の仕様書じゃなくて証明書の仕様書だったし。
見てみよう。

$ openssl x509 -text -noout -in file.bin -inform der
ずらずら~

なんだ、ASN.1での解析とか考えずに、ファイルをまるまる保存すればいいだけじゃないか!
ちっ、手間かけさせやがって。。。

[tool]AsciiDocFXでPDF出力すると、のぺっとする

AsciiDocという形式のテキストファイルを書くと、HTMLやPDFでドキュメントにしやすいという話を聞いた。
API仕様書なんかはDoxygenでやっているのだが、ドキュメントはExcelにしているので、差分がうまく取れず、何を変更したかわからないことがあるのだ。

Windows版のGUIツールもあったので、それをインストールし、まだマーキングはあまりわかってないが、そこそこ書けるようになってきた。


私がドキュメントをリリースするなら、PDFで出したい。
PDF出力もツールからできるのだが、なんかこう、のぺっとしているのが気になる。

 

まず、ツールだとこういう風に見える。

image

これをPDF出力すると、こうなる。

image

ちょっとインデントがほしい。。。

 

いくつか試したが、
  conf\docbook-config\fo-pdf.xsl

  <xsl:param name="body.start.indent">
の数字を変更すると、インデントしてくれるようだ。

2mmにすると、こんな感じ。

image

ちょっと空いたのがわかるかな?

HTMLだと、設定ファイルとしてコピーされた css/asciidoctor-default.cssの65行目あたりのmargin:0をmargin-left:10pxなどにすると、章題もインデントしてくれてよい感じなのだが、まあそこまでは望むまい。

 

色の変更は、
  conf\docbook-config\common.xsl
の最初の方に設定があるから、テーマごと変えるなり、細かく変えるなりすると変更されるみたいだ。
AsciidoctorテーマとColonyテーマの違いがわからんかったが、Foundationテーマはモノクロっぽくなった。

章の上下をもう少し空けたいのだけど、これはこれでやり方がわからなかった。
ファイル名からするとFOPとかいう形式なのだと思うけど、もう調べるのに疲れたのだ。。。
asciidoctorというツールもあるので、そっちもよいかもしれんが、あれはあれで設定がよくわからず、やめてしまった。

[nrf5]SDK v12のble_app_hrsサンプルはけっこう違う

nRF5 SDK v12.0.0がリリースされたが、やはり、いろいろ変わっているようだ。

main.cのSDK v11.0.0との差分を見ると、こんな感じ(小さくてすまん)。

image

DFUが削られているのと、DeviceManagerからPeerManagerになったのが大きいか。
APIバージョンが3だったらATT MTUサイズを設定するところはあるので、それなりに楽しめるのかもしれないが、うちには新しいSoftDeviceが使えるチップが1つしかないし、Androidもそんなに新しくないので、Bluetooth v4.2のところは遊べない。。

 

ソース差分以外にも、いくつか違いがあった。
以前は、nrf_drv_config.hやpstorage_platform.hがそれぞれあったが、sdk_config.hとして1ファイルにまとめられ、ボードごとのフォルダに置くようになった。。。と見せかけつつ、そうでもない。

pstorageのことは載っていないが、pstorage_platform.hは無い。
nrf_drv_config.h相当の内容はありそうだ。
そしてまだよくわからないが、BLEサービスのENABLEDを設定するようになっている。
HRSサンプルだと、BLE_BAS_ENABLED、BLE_DIS_ENABLED、BLE_HRS_ENABLEDが1になっている。
service_init()はいつものようにあるのだが、たとえばBLE_HRS_ENABLEDだとble_hrs.cのところで使われていて、有効になっていないと中身がまるまるコンパイルされないようになっている。

使わないならコンパイルしないようにしておけばいいやん、と思ったが、これはビルド環境を毎回作るのが大変だから、ビルド対象としては全部追加しておいて、ヘッダだけで対象外にできるようにしたいという現れなのか。
Arduino Primoなんかあるから、楽な構築環境を作るのかもしれない。


とまあ、そんな感じで、前作ったものを移植するときはけっこう苦労することになりそうだ。
Bluetooth Developer Studioのテンプレートは提供されているし、その中のmain.cも新しくなっているから、これをベースに作っていった方が早いだろう。

 

その方針で、nRF51822用に作っていたサンプルを変更した。
https://github.com/hirokuma/nrf52832v12_bds_sample

今回からなのかどうかはわからないが、ログ出力のAPIも変わっていた。
nrf_log.hで、NRF_LOG_INFO()を使うようになっていた。

Makefileの変更が一番面倒だった。
私はファイル名を列挙するタイプよりも、+=でずらずら並べる方が、コメントアウトしやすくて好きなのだが、もうそれでやっているとバージョンが変わるたびに変更せんといかんので、負けた。。。

BDSで作ったソースファイルは特に変更していないのだが、ログは変更した。
そのくらいで動いてくれる。

[c/c++]私のC言語 (11) - intptr_tとuintptr_t

あまり決めごとを厳しくしない私のC言語ではあるが、それでもときどき考え込むし、安全のためにはこれでいいんだっけ?と悩むこともある。

それに、安全といっても、どこででも通用するものと、その現場でしか通用しないものがあろう。
せめて、どこででも通用するルールについては把握しておき、そのルールを使うかどうかは別として、使わなかったらどうなるということは知っておきたい。

それを自分で考えるとあやしいので、IPAがせっかくリリースしている資料があるので、使うことにする。

【改訂版】組込みソフトウェア開発向け コーディング作法ガイド[C言語版]Ver.2.0

今見たところでは、2016年4月13日更新になっている。
買うこともできるのだが、PDF版はダウンロードできるのだ。


まだ最初の方を読み始めたばかりなのだが、「信頼性2.7 ポインタの型に気を付ける」(p.49)で立ち止まった。

stdint.hには、intptr_tとuintptr_tという型があり、ポインタ型を格納可能なデータ幅の整数型だとのこと。

ときどきOSで、割り込みハンドラの引数がint型で、そこに渡す数値は自由にできる、というタイプがある。
ポインタを渡したくてもint型なので、intにキャストして、呼ばれた先で戻すのだ。
Windowsだと、LPARAMとかだった気がする。

そういう場合に、こういう型を使うとよい、ということなんだろう。
まあ、提供されたOSだと自分で決められはしないのだが。。。

 

逆のパターンで、引数がvoidポインタ型という方が多いかもしれない。
こちらだと、整数型の変数を用意してアドレスを渡せばよいから、まっとうだろう。

ただ・・・そのためだけにヒープ領域を使うのも心苦しい。
malloc()が使えるなら、渡した後でfree()すればよいかもしれないが、私の環境ではヒープ領域を削ることも多いのだ。
そこで、ポインタ型でアドレスを保存できるサイズなら32bit程度の値は入るということで、整数値をvoidポインタでキャストして、呼ばれた先でまた整数に戻す、ということをしばしば行う。

行儀は悪いと思うのだけど、かといって変数を用意するほどでもないし。。。
じゃあ変数を用意して使い回すかというと、それは危険だから別々に用意したいし。。。
もやもやしつつも、抜け出せていない。

2016/09/05

nRF5 SDK v12.0.0リリース

先週、nRF5 SDK v12.0.0がリリースされた。

今回は、かなり大規模な改修になっている模様。
リリースノート

「Overall」が目立つので、v11とは互換性がなくなっているんじゃなかろうか。
まだ試してないけど。

 

細かく見るよりは、こういうニュース記事の方が雰囲気をつかみやすいかも。

Nordic Semiconductor、最新版nRF5 SDKを発表、署名付きのセキュアなOTAファームウェア・アップデートを導入し、デバイスのセキュリティ向上を支援 - BIGLOBEニュース

Bluetooth v4.2よりもSecure DFUの方を推しているようだ。
まあ、DFUは確かに怖かったので、しくみを用意してくれるのはうれしい。

Arduino Primoのことも書いてあるし、Keilのこともかいてある。
PrimoはKeilで開発しますよ、という流れになって、STM32F1みたいにKeilが自由に使えるようにします!とかなるとうれしいのだがなぁ。

 

すごく気が向けば、試してみよう。
最初に手を出すのに、勇気がいるのよね。

[caffe]cifar10サンプルでclassify.pyは使えんのか

久々に、Ubuntuを仮想環境ではなくインストールした。
14.04のDVDしかなかったので、インストールして、アップグレードしてもらった。
ときどきなぜか固まることがあるのだが、まあよかろう。

 

GeForce GT710という古いグラフィックスボードだが、これでもCPUで計算するよりも速い(はず)。
CaffeとCUDA8.0RCなどをインストールした。


もう使い方を覚えていないから、ネットで見ながら動作確認を行った。

CaffeでDeep Learning (2) - 桜朔
[deep learning] caffeとCIFAR-10を使って画像判別テスト(詳細) - 脳汁portal

 

動いたのだが、どちらの人もclassify.pyを使っていない。
io.pyを修正しても、なんかちゃんとした結果を出していないような気がするのだが、そもそも何なのかがよくわかっていないので、推測ができん。

 

まず思ったのは、classify.pyで省略した引数が影響しているのではないか、ということだ。
"--mean_file"があやしい。
デフォルトでは、'caffe/imagenet/ilsvrc_2012_mean.npy'を使っているのだが、これはILSVRC2012用だろう。
cifar10は、CIFAR-10のmean_fileを指定すべきではなかろうか。

ただ、python/caffeの下にはCIFAR-10用と思われるファイルがない。
このnpyファイルは、numpy array形式のファイルらしく、"data set image mean of [Channels x Height x Width]"と説明があるから、平均画像なのだろう。

CIFAR-10サンプルの平均画像は、mean.binaryprotoというファイルになるようだ。
これを指定すればよいかと思ったが、エラーになった。
形式が違うようだ。

Convert binaryproto to npy | Rachel's Memo
Pythonのコードが載っているが、open/readはしているが、writeはしていないから、arrという変数がnpy形式ということになるのか。
最後に「np.save(ファイル名, arr)」とすると、arrの内容をファイル保存するようだ。

これをclassify.pyの--mean_fileに指定すると、ずいぶん進むようになったが、今度は次元数が違っているというような感じがする。
いや、ndimじゃなくてlen()だから、次元ではないか。
io.pyでは、2か3(2だったら1足している)を通すようなのだが、変換したデータは4になっている。
変換データのshapeは(1, 3, 32, 32)だから、これが4つあるからlen()が4なのか。

最初にmean.binaryprotoを作る場合は、コマンドbuild/tools/convert_imagesetを使っている。
lmdbとあるから、lmdbフォーマットがbinaryproto形式ということか。
(1, 3, 32, 32)のうち、最後の2つはデータのWidth x Heightだろうし、その手前はRGBの3 layerだろう。
classify.pyがほしいのは"[Channels x Height x Width]"ということだから、最初の"1"がいらないだけなのかな。

「arr = np.reshape(arr, (3, 32, 32))」とすると、(3, 32, 32)になった。

import caffe
import numpy as np
import sys

param = sys.argv

blob = caffe.proto.caffe_pb2.BlobProto()
data = open( param[1] , 'rb' ).read()
blob.ParseFromString(data)
arr = np.array( caffe.io.blobproto_to_array(blob) )
arr = np.reshape(arr, (3, 32, 32))
np.save(param[2], arr)

わざわざparamに移したり、arrに2回代入したりと格好は悪いが、ネットで調べながらだから許しておくれ。

 

これで(3, 32, 32)になったし、classify.pyの--mean_fileに指定してもエラーにならなかったが、show_result.pyで見てもパーセントが0だ。
何か違うのか。。。


ああ、--model_defと--pretrained_modelも指定しないといかんのか。
2番目のサイトのスクリプトをまねしよう。

$ python python/classify.py ./car.jpg ./result.npy --mean_file=cifar10.npy \
--model_def=examples/cifar10/cifar10_quick.prototxt \
--pretrained_model=examples/cifar10/cifar10_quick_iter_4000.caffemodel.h5

$ python python/show_npy.py result.npy
#1 | dog | 42.7%
#2 | cat | 31.8%
#3 | airplane | 11.0%

数字は出たのだが、結果がおかしいな。。。
2番目のサイトにある、猫がアップになった画像だと、こうなった。

#1 | bird | 29.0%
#2 | airplane | 20.9%
#3 | cat | 13.8%

全然違うなぁ。
同じスクリプトをうちでも動かしたが、数値は異なるもののネコが一番高くなるところは同じだ。

====================================
possibility of each categoly
0(airplane):   0.184532
1(automobile): 0.000219549
2(bird):       0.0134824
3(cat):        0.539376
4(deer):       0.0715057
5(dog):        0.021061
6(frog):       0.0255798
7(horse):      6.09221e-07
8(ship):       0.136054
9(truck):      0.00818893
====================================
I guess this image is [cat]

数字が違うというのも気にはなるのだが、半年違いがあるからネットワークが少し変わったのかもしれない、と勝手に思うことにしよう。

載っているスクリプトもmean.binaryprotoをreshape()しているから、意味として同じようなことをやってるんだと思う。
なにが、何が違う。。。。

あー、images_dimだ。
classify.pyはデフォルトだと256,256なのだが、載っているスクリプトでは省略していて、caffe/classifier.pyのデフォルトは画像サイズ、つまり32,32になっていたのだ。

 

なんだー、じゃあ、そこも指定して動かしておしまい。。。と思ったら、Ubuntuが死んでしまった。。。
メモリテストも正常だったし、インストールも新規だったし、あとはnVIDIAのドライバか、AMDのドライバか?


リセットして動かしたが、まだ合わない。。。
ここまで指定して、ようやく結果が一致した。

$ python python/classify.py ./cat.jpg ./result.npy --mean_file=cifar10.npy \
--model_def=examples/cifar10/cifar10_quick.prototxt \
--pretrained_model=examples/cifar10/cifar10_quick_iter_4000.caffemodel.h5 \
--images_dim=32,32 --center_only --channel_swap=0,1,2

$ python python/show_result.py data/cifar10/batches.meta.txt ./result.npy
#1 | cat | 53.9%
#2 | airplane | 18.5%
#3 | ship | 13.6%

 

こういう目にあうと、DeepLearningはともかく、Pythonには少し近づけたかもしれない。

2016/09/04

[nfc]マイナンバーカードとIC運転免許証

Facebookで、IC運転免許証の仕様書が更新されていることを教えてもらった。
いやあ、まったく気付いてなかったですわ。
運転免許証及び運転免許証作成システム等の仕様の改正について(PDF)

仕様書V7になったようなのだけど、2016/07/15に施行された道路交通法の変更が理由らしい。
たぶん、これじゃなかろうか。
道路交通法の一部を改正する法律の施行に伴う交通警察の運営について(PDF)
車を持ってないので、どうも疎いのよねぇ。。
免許更新に行くと説明してくれるからわかるのだが、PDFを読んでもよくわからん。
免許で乗ることができる車種が変わったりするけど、あの区分が変わったとかか?

 

そもそも、どこで更新されているのかを把握すればよいのかわかっていなかったのだが、警察庁の運転免許課というところに出るようだった。
検索だと、新しい情報は出てきにくいのだ。
警察庁の施策を示す通達(交通局)|警察庁

つらつらと見ていくと、免許証以外にも気になるものがあった。

 

運転免許証の記載事項変更の届出手続における個人番号カード及び通知カードの取扱いに関する留意事項について(PDF)

これは2ページぐらいだから、すぐに読める。
大ざっぱに言うと、免許の住所変更のときにはマイナンバーカードで住所変更されているかも確認しなさいよ、ということだ。
だったら、マイナンバーカードの更新時に免許の方も同時にやってくれたらいいんだけどねぇ。
「管轄が違う」ってやつですか。

 

 

こんなのもあった。
ICカード免許証の暗証番号の運用に係る留意事項について

こっちは、なんか愚痴っぽい。
「暗証番号1を忘れている人が多いので、IC運転免許証の民間での使用普及が広間欄じゃないか!」みたいな。

で、暗証番号1を使って読込を行っても免許証を見てわかることしかわからないので、じゃあ免許証を見てわかるものを暗証番号1にしてもいいんじゃないか、という提案みたい。

以下、スクリーンショットはPDFから取ったものだ。

image

へー。

一番最後に検討したときの結果が書いてあって、結局「暗証番号1で読み取れる内容での本人確認は確実じゃないし、使っている民間企業も今のところ確認できない」ということらしい。

暗証番号1で読み取ることができる情報は、こうなっている。
暗証番号無しだと、たとえばポケットに入れているカードから情報を吸い上げられる可能性があるから、少なくとも暗証番号の設定は必要だ、ということになっている。

image

どっちかといえば、カードの券面にこういう情報を載せないようにして、暗証番号1を打ち込まないと読めない、という運用の方がいいんじゃなかろうか?
まあ、暗証番号1を忘れてしまっているからそういう運用ができない、ということなんだろうけど。。。

それに、そうしてしまったら、拾ったカードを交番に届けても、カードを読めないと誰のかわからないが、誰のかわからないとカードを読めないことになるのか。。。
難しいねぇ。

2016/09/03

公開鍵を読んでの感想

今回、公的個人認証の公開鍵を読んだが、PaSoRiを使ったりしたものの、基本的にはAAA Blogさんの記事をなぞっただけだ。
特別に解析などはしていない。

苦労したのは、ASN.1がわからんとか、opensslのコマンドがわからんとか、Type-Bのアクセス方法がわからんとか、直接カードとは関係がないところだった。


省略して「マイナンバーの公開鍵」と書いたりもしたが、公的個人認証の部分だけしかアクセスしていないし、そこにはいわゆる4情報も入っていなかった。
文字で見てわかる情報は、こんなところだ。

  • countryNameなど
    • JPと出てくるので、日本であることがわかってしまう
  • organizationNameなど
    • JPKIと出てくるので、日本であることがわかってしまう
  • 「公的個人認証サービス」とか「地方公共団体情報システム機構」とか出てくる
    • 日本語だ!
  • X590v3 CRL Distribution Points
    • たぶん発行した区役所の場所になっている(うちだと、Fukuoka-ken, Fukuoka-shi,-Hakata-ku)
  • よくわからんOIDだが、たぶん有効期間の満了日
    • 発行から5回目の誕生日だから、誕生日がバレる!

この情報は、JPKI利用者ツールで取得できるものとだいたい同じだ。
誕生日はバレるが、生年月日はわからないからセーフなのかな?

一応、個人番号で取得したデータを検索してみたが、正順、逆順、ASCII変換で探しても出てこなかったから、少なくとも素のままでは入ってないだろう。
まあ、ファイル構造がわからないから、他がどうなっているかは知らないけど、入れる意味はないと思う。


そんな感じだ。

自分で調べたところがあまりないので、他人のふんどしで相撲を取ったような感じもするが、夏休みの自由研究だからよいのだ。

[nfc]公開鍵をopensslで使ってみよう

マイナンバーカードから公開鍵を読めたとしよう。
そこからどうしたらよいのだ?
ここからは、私の知らない世界だ。

 

私の中では、こういうRSAとかはopensslを使うものだろう、というイメージがあるので、それでやってみた。
が・・・、openssl rsaでもopenssl rsautlでも、公開鍵として読めない、と言われる。
openssl asn1parseをDERオプション指定では読めるので、ASN.1としては正しいはず。。。

 

RSA公開鍵のファイル形式とfingerprint - Qiita
こちらを見ると、取得した公開鍵の形式はpkcs#1のような気がする。
サイズが同じだし、タグがSEQUENCE-INTEGER-INTEGERの構成だから、というだけの根拠だが。。。

 

ssh接続用の公開鍵( ssh-rsa public key )をopensslで使える形式( X.509 PEM )にshellscriptで変換する Mac OS X ( Convert ssh-rsa public key to pem )
なんと、pkcs#1はopensslでは使えないようだ、との記述が。

でも、opensslの-informの説明では、"DER"はPKCS#1フォーマットと互換のあるASN1エンコード、と書いているのだが、実際使えないから、何か違うのかもしれん。

 

openssl - How can I transform between the two styles of public key format, one "BEGIN RSA PUBLIC KEY", the other is "BEGIN PUBLIC KEY" - Stack Overflow
お、こちらの2番目の回答者は、rsaEncryptionだけじゃなくて、もうちょっと上の方から、データに含めているようだ。

さっきまで試していたのは、図で言えば赤線で囲んだ枠の中だけのデータだったのだが、回答者は青線で囲んだ枠の部分をデータにしているのだ。

image

 

$ openssl rsautl -encrypt -pubin -inkey file.bin -keyform DER -in
mine.txt -out mine.enc
$

おー、通った。
file.binが青枠の部分をファイルにしたもので、mine.txtは符号化用に作った短いテキストファイルだ。

実際は、mine.txtのダイジェストを取って、それを符号化するんだったような。
じゃないと、長い文章なんかはそのまま符号化できないからだ。
復号するところも試してみたいが、秘密鍵は持っていないのでできない。


実際は、符号化するのはカード側で、opensslで行うのは復号の方だ。
カードには、暗号化したいデータを書けばよいのかな。
マイナンバーカードでSSHする - AAA Blog

"PKCS1形式のハッシュ値"と、また聞いたことのない形式が出てきた。。。
単に符号化するだけだったら、データ形式は関係ないのでは?と思いたいのだが、今までがASN.1というかpkcs#1形式だっただけに、ちゃんとINTEGERとか付けないとだめなのかもしれん。

こういうのは、OpenSCのソースを見るのがよいのだろうが・・・。
sc_pkcs15_compute_signature()をpkcs15-crypt.cなどが呼んでいるところまではわかったのだが、深入りしない方がよい感触だ。

 

では、気にせず適当に値を投げてみればよかろう。
暗証番号が間違えばカウントが減りそうだけど、ここで間違っていても減らないだろう。

よくわからない0x2AコマンドはType-BのCase4Shortなので、ヘッダと、Lc、データ、Leで構成される。
Lcはデータのサイズで、Leは2048bitということで00にしておけば256バイトになるだろう。

あ・・・256バイトのレスポンスなんて対応してないぞ。
Normalフレームでの送受信しかやっていないのだ。
Extendedフレームにした場合は265バイトまでいけるんだけど、入るのか?
レスポンスが256バイト、それにInDataExchangeのレスポンスコード、ステータスフラグで3バイト、SWで2バイト。
261バイトだから、収まるのか。
PN532のドキュメントでは、R-APDUは258バイトまでとなっているが、APDUの部分だったら満たしているから大丈夫か。

今までExtendedフレームなんて対応したことないから、参ったな。。。
あ、昔の私偉い!対応してた!!

 

では、やってみて、受信したデータを公開鍵で復号してみよう。

$ openssl rsautl -verify -pubin -inkey file.bin -keyform DER -in
sig.bin -out sig.txt
$ cat sig.txt
my number card!

おー、出た出た、やりおったわ。
カードの方に「my number card!」というデータを書いて、それによって戻ってきたデータをsig.binに保存して、それを先ほどの公開鍵で復号したのだ(公開鍵でやるときは、-decryptじゃなくて-verifyなのだね)。

 

夏休みの自由研究は、これで終わりにしよう。
やれやれ。

[nfc]公開鍵は読めたので、よしとしよう

前回の続き。

公開鍵などが入ったファイルをdumpasn1aatool2の両方で解析した結果を見比べて、ようやくわかった。

ASN.1には、object identifier(OID)というものがあり、それを見てどういうデータなのかを判断すればよいのだろう。
おそらくRSA公開鍵は、1.2.840.113549.1.1.1だ。

image

検索すると、JPKIの資料にも出ていた。
OIDが1.2.840.113549.1.1.1で、NULLで、BIT STRINGがあれば、BIT STRINGのところが公開鍵だと思っていいんじゃなかろうかね。

 

あー、でもこれをデータの頭から見て行くには、ASN.1を自前で解析できないといかんのか。。。
少なくとも、サイズ分スキップしたり、構造型オブジェクトで入れ子になったものを判断したりできないといかんな。

こっから先はNFCと関係ないので、ひとまず公開鍵が読めたし、解析方法もわかったということで満足しよう。

[nfc]公開鍵を読む

夏休みの自由研究も最後だ。

なんで公開鍵でNFCなのかというと、以前中断したマイナンバーカードだからだ。

マイナンバーカードでSSHする - AAA Blog
こちらのアプリで動かせればよかったのだが、うちのPaSoRiでは動かなかったので、しょうがなくソースを読んで、SELECT FILEとREAD BINARYした。

動かしている方の情報を見ていると、公開鍵を取得するときには暗証番号の入力をしていないようだったから、きっとREAD BINARYしてるだけだろう、と当たりを付けて、コミット履歴から探していった。

・・・というのは結果の話で、そこに行き着くまでがかなり大変だったのだ。
自由研究にふさわしいのだけど、書いてよい情報かわからんので、書かない。

 

公開鍵を読む、といっても、どうやって読んだデータが公開鍵か判断するんだ?と思われるかもしれんが、それはJPKI利用者ソフトという公的なツールがあって、それが公開鍵情報も出力するのだ。
だから、読み出したバイナリデータを検索して、一致するデータを探していったのだ。

実のところ、データは読み出せたものの、他にもいろいろデータが入っているので、公開鍵だけを抜き出す、というところまではできていない。
がさっとバケツで水をすくったような形だ。

バイナリデータは、ASN.1という形式のようだ。
たぶん、うまく抜き出してOpenSSLなどを使えば、他でも使える形式に変換できるんだろう。
そして、カードには秘密鍵で符号化する装置が入っているから、電子署名として使うことができるというわけだ。

 

総務省の資料を見ていると、何のアクセスか忘れたが、1件あたりいくらにしようか、というような検討が行われていたけど、この部分は問い合わせがいらないから、きっと無料で使えるんだろう。
まあ、5年ごとに更新する必要はあるんだろうが。。。

あれ、5年経ったからってカードが読めなくなるわけじゃないよね?
ならば、失効を気にしなければずっと使えるのか。。。

2016/09/02

サーボモータを動かそう

夏休みの自由研究、第2弾だ。
サーボモータを動かそう。

Arduinoスターターキットを購入したとき、サーボモータも一緒に入っていた。
SM-S2309Sと書いてある。
http://descargas.cetronic.es/microservo.pdf

PWMを入れることで動かすらしいのだが、PDFにはその仕様が書かれていないな。。。
ということは、単なるアナログ入力で、それをPWMで代替えしているということか。

 

前回作ったブザーを鳴らすアプリを変更することにした。
PWMの停止ができるし、PWMの調整するところまで実装しているから、Duty比を変えるだけでよいはず。

その前に、電圧のことを考えねば。
NUCLEOは3.3Vだけど、サーボモータは5Vなのだ。
アナログ電圧で制御するなら3.3Vでも動くのかもしれんが、よくわからんのに冒険はしたくない。

幸い、ロジックレベルの変換ができるチップを持っていた。
TXB0104搭載4CH双方向レベルコンバータ - スイッチサイエンス

上が3.3.V側、下が5V側。
オシロじゃないから電圧が変わったかわからんが、電気的に変換しているから時差はないのだな。

image

 

制御のさせ方は、こちらを参考にした。
サーボモータの制御

Arduinoスターターキットの本には、map()で制御する、しか書かれていないのでわからんのだ。

波長は15m~20msecらしいので、10msecにしてみよう。
以前計算した式から、

tick = APB1 / (Prescaler+1) = 84MHz / 8400 = 10kHz
PWM = tick / (Counter Period+1) = 10kHz / 100 = 100Hz
周期 = 1 / 100Hz = 10msec
Duty比 = Pulse / (Counter Period+1)

上記のページでは、13msecに対して1~2msecで動かしているから、Duty比は10~20%か。
100HzだとPulseはちょうどDuty比と同じだから、これでは10段階程度しか動かせんな。

まあいいや。


ソースを載せるほどではないので省略するが、動いた。
サーボ側の5VとGNDは、スターターキットの本に100uFの電解コンデンサでつないでおくように書かれていたから、まねした。
回転するときに電圧が下がるからかな?

しかし、Arduinoとは直接接続しているから、モータの時みたいにドライバを挟むほどではないようだ。
電源は別に取っているからそうなるのか。

うちのサーボさんは、Pulseを5~24の間で動いた。
4とかだと、少しうなるような音が聞こえたので、動くか動かないかのところで震えたのだろうか。

180度を10段階だから、18度ずつ動いたことになるだろう。
多少粗いが、そういうのはPreScaleを小さくして、tickが大きい値になるようにすればよかろう。

意外と、3.3VでもDuty比を上げれば動くんじゃなかろうか、とつないでみたが、90にしても動かなかった。
3.3Vを挿しても動かないので、やはりPWMじゃないとダメなのか?

 

まあ、あまり深くは考えまい。


[2016/09/02 21:41追記]

もう少し細かい情報が書かれているサイトがあった。
ブックマークまでしていたのに、なぜ見ていなかったんだ。。。

Arduinoで学ぶ基礎からのモーター制御:基礎からのマイコンモーター制御(6):PWMを使ったサーボモーターの制御 (1/3) - MONOist(モノイスト)

これの2ページ目に、波長が20msecで、H区間を1~2msecで変化させる、と書いてあった。
1msecが0度、2msecが180度になるとのこと。
やってみよう。

tick = APB1 / (Prescaler+1) = 84MHz / 8400 = 10kHz
PWM = tick / (Counter Period+1) = 10kHz / 200 = 50Hz
周期 = 1 / 50Hz = 20msec
Duty比 = Pulse / (Counter Period+1)

これで、Pulseを9~19にすればよいはず。

・・・ダメだ、そんなに精度がよくないんだった。

image

image

 

手作業で調整したときの波形を計測した。
うーん、単にパルスの幅だけで動いているとしたら、500us~2300usくらいになってるんじゃないか?

image

image

 

こちらを見ると、同じSG90を使っているのだが、動作パルス幅が500us~2400usになっていた。

Netduino: サーボモーターをコントロールしよう - Build Insider

波長はそのままで、パルス幅を500us~2400usになるように値を変えると、同じように動いた。
だから、パルス幅を見てるんだな。

[c/c++]私のC言語 (10) - "-lpthread"と"-pthread"

ようやく10回目を迎えた。
別に回数をどうこうという訳ではないのだがね。

 

このシリーズを書き始めたのは、ネットで検索した情報を見て、「組み込みって、なんかルールがきつそうだからやりたくない」と思われるんじゃなかろうか、と勝手に思ったので、「分野によってはそうでもないのだよ」ということを言いたくて始めたような気がする。

私は、けっこうリソースに余裕がある組み込みをやることが多い。
LinuxのようなOSが動く場合はもとより、ARMだったら32bitだし、RL78は16bitだったのできつかったなぁ、とか、そういう感じだ。

また、nRF51822やESP8266のように機能とセットになったマイコンを使うことも多い。
そうなると、載せ替えるとしても同じマイコン系列になるため、移植性を考えても仕方がないので、そこに時間を割くよりは、さっさと実装してしまおう、となっている。

そこら辺の事情があるから、値がだいたい収まるならintで済ますし、変数宣言の順番も数バイトくらいなら空きがあってもいいや、と思ってわかりやすい順に並べている。
たぶん、そういうのを気にする人と一緒にコーディングしていたら、相手はかなりイライラするんじゃなかろうか。。


本題に戻る。

今回はLinux限定かもしれんが、C11ではスレッドが使えるらしいので将来的にはわからんが、まあLinux限定としよう。

いつからか忘れたが、POSIXスレッドを使ってコンパイルするときのオプションとして「-pthread」があるのに気付いた。
たぶん、どこかの記事を見たのだと思う。
「この人、"l"を忘れてるやん」と思っていたのだが、ライブラリのリンクではなくてオプションだったのだ。

multithreading - Difference between -pthread and -lpthread while compiling - Stack Overflow
どうも、プリプロセスの段階で違いがあるようだ。
確かに私が持っている古いLinuxの本でも「-D_REENTRANT」を指定するように書かれている。

もしかしたらコンパイル段階でも違うかもしれん誌、GCCのバージョンによっても変わってるかもしれんね。

 

まあ、カバレッジも--coverageオプションになったようだし、コンパイル時点で働きかけるというのは流行りなのかもしれん。

2016/09/01

FeliCa Plugで搬送波検出

FeliCa Linkが出てきたので、FeliCa Plugは使ってないなあ、という方も多かろう。
それなら、搬送波検出器にしてしまえば、何かと役に立つかもしれない。

image

 

FeliCa Plugとピン番号の関係は、こうなっている。
コネクタ側を下にしたら、左側が1番ピンだ。

image

 

搬送波が出ているところにかざすと、光る。

image

右上にあるのは、microUSBからの5Vを3.3Vに変換するものだ。
電池で動くのだけど、電池フォルダを持ってなくてね。。

 

さあ、夏休みの自由研究に困っていたら、使ってもよいのだぞ?