2015/02/22

[mbed]初mbedはNUCLEO-F411RE

スイッチサイエンスさんから、mbedを買った。
Cortex-M3は2つあるし、M0は1つあるので、M0+にするかM4にするか迷った末、M4にした。
ST Nucleo Board STM32F411RET6 - スイッチサイエンス
RS Onlineの方が本体価格は安かったんだけど、ブレッドボードもほしかったので。
一緒に、イーサネットをつなぐ部品も買った。まあ、使うかはわからんけど。
mbed用イーサネット接続キット - スイッチサイエンス

私の予定では、ブレッドボードを2枚横につなげて、そこにmbedを載せるつもりだった。
が、横につなげるとピンの幅が合わないのね・・・。
まあ、ばらばらにすれば使えるから、よしとしよう。

埋め込み画像への固定リンク

 

PCにUSBでつなぐと、ST-Linkとかのドライバがないと言われる。
mbedのページに行って、アカウントを追加して、デバイスとしてF411REを追加すると、情報ページが出てきた。
そこにFirmwareを新しくしてね、とあるのでリンク先に飛ぶと、先にST-Linkのドライバを入れる、というリンクが出てきたので、そこからダウンロードして実行すると、ドライバが追加された。
Firmwareのファイルも、ダウンロードして実行すると、焼かれた(USBスニファを起動していたためか、最初はNUCLEOに焼いているFirmwareを読めなかった)。

あとは、作ったアカウントにプロジェクトを新規作成し、ひな形としてLED点滅のを選び、適当に時間を変更してコンパイル。
そうするとbinファイルがダウンロードされるので、それをUSBメモリとして見えているNUCLEOに置くだけ。
焼いてる間は、USBコネクタ近くのLEDがちかちかするみたいだ。

LEDは3つあり、1つはUSB通信の状態とかを表すやつ、1つがユーザ用、もう1つが電源状態用になっている。
で、この電源LEDなんだけど、とてもまぶしい。
基板の文字が読めないくらいだ。
これはマイコンとはつながっておらず、電源から直につながっている。
R32をはずせばいいんだけど、それもなぁ。
というわけで、シールを上から貼る、というアナログな方法で対応した。
まあ、一種のOut of Bandな対策ですな。

そういえば、Nexus5でUSBメモリをマウントできたので、Androidから焼けるかどうか試そうとした。
が、Nexus Media ImporterがFAT12に対応してないらしく、マウントができなかった。
残念。

USBのパケットキャプチャ

今まで、USBのパケットキャプチャにSnoopyProを使っていた。
よかったのだけど、Windows7にしてから動かなくなったように思う。
まあ、元々がXPで動作確認と書いてあるから仕方ないのだが・・・。

以前、TIのBLEスニファをWireSharkで見る際、USBpcapを使った。
これは、USBのパケットをWireSharkで見たかったので使ったのだけど、キャプチャする対象がハブかポートかわからないけど大きなまとまりでしかできなかった。
なので、場合によっては意図してないパケットまで入り込んでしまい、ちょっとわずらわしい。

今回見つけたのは、Free Device Monitoring Studio
これはなかなかよかった。
フリー版の制限で12分までってなってるが、それなら困りはしない。
が・・・さっき気付いたんだが、Grace Periodってことで4日間だけなのか。
がーん。
4日間はフル機能が使える、という意味だったらよいのだが・・・。

でも、こっちのサイトを見ると、お金のことは書いてないな。
そもそも、上のページでも「Zero price software」とあるしなぁ。
しばらく使ってみよう。

[libusb]Enumerationができていなかったのは、私が悪かった

前回、USB_NODE_CONNECTION_INFORMATION_EXのメモリ確保について書いたが、よくよく考えるとそれが原因ではないと思う。
もしメモリが足りないのだったら、APIがエラーを返すべきなのだ。
メモリが足りない→APIは未接続で返す、ということにはならないだろう。

 

デバッグ出力を追加して見ていったのだが、どうもNoDeviceConnectedで返しているときはVIDやPIDが0x0000になっていて、usbviewでNoDeviceConnectedを返しているタイミングと同じようだ。
libusb_open()で失敗しているのはこんな深いレベルじゃなくて、単に判定のしかたが足りてないだけか?
うわっ・・・私のEnumeration、甘過ぎ・・・?

 

こんな順番で、対象の機器を探していた。

  1. libusb_init()
  2. libusb_get_device_list()
  3. libusb_get_device_descriptor()
    1. VIDとPIDが一致するまで、ぐるぐる回す
    2. break
  4. libusb_open()

この4番でopenに失敗するとみなしていた。
しかし今回のデバイスは、デバイスマネージャーで見ると同じ名前で複数出てくる。
zadigでも、Interface0、Interface1、みたいに出てきていた。
だからかわからないが、最初にVIDとPIDが一致しただけで判断するのではだめなようだ。

  1. libusb_init()
  2. libusb_get_device_list()
  3. libusb_get_device_descriptor()
    1. VIDとPIDが一致するまで、ぐるぐる回す
      1. libusb_open()
      2. 成功したらbreak

こんな感じで、できた。
libusb、疑ってすまんかった。

2015/02/21

[libusb]usbviewとlibusbのこまごまとした違い (1)

【これまでのあらすじ】
あるUSBデバイスをlibusbで見てみよう、と軽く考えたhiro99ma。
いつものようにzadigでWinUSBドライバに変更したものの、libusbのオープンすらできない。
どうもEnumerationあたりに原因がありそうなのだが・・・・?

 

まだ解決には至っていないが、整理がてらメモを残しておく。

今はWinUSBのサンプルとしてusbviewを見つつ、libusbのEnumerationとどう違うのかを見ていっている。
一応、私のUSBスキルの話をしておくと、無いに等しい。
ときどきネタとしてlibusbのことを書いているが、だいたいは動いている前提でバルク転送するだけしかやってないのだ。
動かないときはzadigでドライバを差し替えるだけ。
今回のように、実装にせよ内部のことを見るのははじめてだ。

で、素人っぽくAPIの使い方を見ていったのだが、そんなに違いはなさそう。
ただ、APIに渡すパラメータがいくつか違う。

最初に気付いた違いは、サイズだ。
libusbはUSB_NODE_CONNECTION_INFORMATION_EXのsizeofをそのまま設定しているのだが、usbviewではsizeof(USB_NODE_CONNECTION_INFORMATION_EX) + (sizeof(USB_PIPE_INFO) * 30)という大きい値を渡している。
なんかUSB_NODE_CONNECTION_INFORMATION_EX構造体の定義を見ると、こうなってた。

typedef struct _USB_NODE_CONNECTION_INFORMATION_EX {
  ・・省略・・
  USB_PIPE_INFO PipeList[0];
}USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX;

確かこの記述方法は、C99あたりで採用されたものじゃなかったろうか。
つまり、一番最後に可変なメンバを置き、malloc()などでサイズを自由に確保するやつだ。

大ざっぱな書き方をすると、こんな感じか。

struct image_x {
  uint8_t r;
  uint8_t g;
  uint8_t b;
  uint8_t alpha;
};

struct image {
  int width;
  int height;
  image_x  pix[0];
};

int width = どっかから横幅を取得;
int height = おなじく縦幅を取得;
image *pImageArray = (image *)malloc(sizeof(image) + sizeof(image_x) * width * height));

なんとなく、イメージが伝わればよいが。
以前は、配列要素に「0」を指定できなかったので、上記をこうやって書いていたそうだ。

int width = どっかから横幅を取得;
int height = おなじく縦幅を取得;
image *pImageArray = (image *)malloc(sizeof(image) + sizeof(image_x) * (width – 1) * height));

[1]とする以上、1つ分のメモリは確保されるので、それを差し引いた分を確保するという意味だ。

 

細かい中身はよいとして、比較で気になったのは、libusbはこのメンバをスタックで確保していたのに対し、usbviewはポインタで確保してmalloc()で割り当てていたというところだ。
だから、IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EXで取得した値すべてを渡すにはメモリが足らずに失敗していた、という筋書きじゃなかろうかと。

・・・違うね。
少なくとも、サイズだけが原因ではないようだった(暫定でメモリを増やして試した)。
DeviceIoControl()自体は成功していて、このデバイスに対しては戻ってきたサイズが小さいものなぁ。

 

今回は私の負けだが、それで終わりではないぞ。

[winusb]USBView sampleをVisualStudio 2013 Communityでビルド

WinUSBでUSBのEnumerationをしてみれば、libusbでエラーになっているところの意味がわかるかも。
そういうわけで、VisualStudio CommunityでUSBViewをビルドしてみた。

 

いるもの

 

WDKが入ってない状態でビルドすると、ApplicationForDriversが足りない、みたいなエラーが出る。
インストーラでインストールすれば、特に設定とかしなくてもビルドが通った。
いい時代になったものだ・・・・。

[libusb]libusb-1.0をcygwinでビルド

念のため、libusbを自分でビルドしてみよう。
今はcygwinのインストーラで入ってきたdllを使ったのだけど、もしかしたら実行している環境でビルドすると何か違うかもしれん。
まあ、そんなことはないんだろうけどさ・・・。

ソースがgithubにあった。
libusb/libusb

cygwinでビルドする場合は、INSTALLを見る。configure→make、というおなじみの流れのようだ。
あれ・・・configureがないやん。
よくわからんが、configure.acとかあるんで、作り出すことができるようだ。
configureの作り方(autotoolsの使い方) - メモ。。メモ。。
今は、これにlibtoolizeというコマンドを実行せんと、ltmain.shがない、というエラーが出るようだ。
最初に実行すればよいのかな?
出てから実行したので、順番はよくわからん。

あと、gccのバージョンによるのかもしれんが、stricmp()がないと怒られた。
これは、windows_usb.hの#defineを_stricmp()からstrcasecmp()に置き換えた。
c++ - g++ error: ‘stricmp’ was not declared in this scope (but OK for 'strcmp') - Stack Overflow

これでビルドできた。
が、結果は変わらん。
まあ、そうよね。

[libusb]Win8+特定デバイスでうまくいかん

うまくいかんシリーズだ。

あるUSBデバイスをlibusb-1.0で動かそうとした。
プラットフォームは、Windows8。
cygwinのインストーラでlibusb-1.0を選択してインストール。
ドライバはzadigを使用して、WinUSBを使う(libusb-win32などを選んでしまいがちだが、libusb-1.0はWinUSBベースで動いているはず)。

で、ここまではよかったのだ。
あとは、libusbでデバイスを検索して、オープンして、アクセスするだけ。
だけなんだけど、libusb_open()でエラーになった。
戻り値は-12で、LIBUSB_ERROR_NOT_SUPPORTED。

しかし、libusbのデバッグ出力を有効にして動かすと、USB機器の一覧(Enumeration)をしているときに、既にエラーとなっていることがわかった。
win32でDeviceIoControl(IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX)を投げているのだが、それで取得した状態がNoDeviceConnectedとなっているのだ。
NoDeviceConnectedなデバイスをlibusb_open()すると、LIBUSB_ERROR_NOT_SUPPORTEDになるというしくみ。

 

それだけだと、なんかlibusbの使い方がおかしいのかな、と思うところだが、そう言いきれないところが残っている。

まず、同じプログラムをWindows7 sp3 64bitのcygwin(32bit)で動かしたのだが、それでは問題がない。
どちらかといえば、Win7で動くことを確認したからWin8でやろうとした、というところだ。

ではWin8でlibusbがうまく動かないかというと、そうではない。
PaSoRiをつないで動かしたのだが、そこではエラーが出るわけでもなく、ちゃんと動いた。
動くのを確認し、PaSoRiをつないだまま対象のデバイスをUSB接続し、その状態でPaSoRiを制御しようとすると、同じエラーが出つつもちゃんと動いた。
つまり、出ているエラーというのはUSBデバイスを列挙する段階で出ているだけで、制御対象にしようとしたデバイスから出ていたわけではないということになる。

ということは、単にDeviceIoControl(IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX)が特定のデバイスで失敗するだけではないか、と思った。
その確認をするのは、ちょっと私では荷が重い。
なので、ひとまずMicrosoftが出しているUSB機器を見るツール、usbview.exeを使ってみた。
・・・うん、これは特定デバイスであっても情報がちゃんと表示されている。
うーむうーむ・・・。

 

昔の私も、同じようなことを調べていたみたいだ。
hiro99ma blog: libusb_open()でLIBUSB_ERROR_NOT_SUPPORTEDが返ってくるが、わからん
当時は、WinUSBドライバじゃなくてlibusb-win32ドライバを使っていたのでだめだったようだ。
hiro99ma blog: libusb-1.0はzadigを使うべし
しかし、今回は状況が違う。
動くデバイスと動かないデバイスがあるし、PCに因るのかOSに因るのかはわからないが動いているPCと動いていないPCがある。


エラーが起きているタイミングは、libusb_init()後にlibusb_get_device_list()している間だ。
つまり・・・まだどのUSBデバイスを使いたいとか決める前。
サンプルだってそれ以上のことをしていないし、サンプルをlibusb_set_debug(NULL,3)して動かすとエラーが出ている。
libusb/listdevs.c at master · libusb/libusb

というわけで、この問題はlibusbよりもWinUSBの方を先に見ていった方が早いように思った。

2015/02/14

[qt]今、Qtは5.4.0が最新(2015/02月)

フォルダの整理をしていたら、Qtがあった。
そういえば、最近なにもしてなかったな・・・。
今はどうなってるんだろう?

手元にはバージョンが5.1.1になっている。
サイトを見ると、5.4になってた。
当時のメンテナンスツールはまだ使えるのだろうか?
先にアップデートしろ、と言われたので実行して立ち上げ直すと、日本語になった。

image

コンポーネントの選択を見ると、5.4があった。
が・・・どれをチェックすればよいのかよくわからん。

image

 

アップデートしてQt Creatorを起動したが、大きく変わったような感じはしない。
以前は、インストールすると拡張子に関連づけたアプリの設定まで奪ってしまったような気がするが、今回はインストーラが走るときに選択できたような気がする(なんとなく進めていたので、記憶が薄い。。)。

Qt 5.1.1で作っていたプロジェクトがあったのでビルドさせたが、MinGWだと普通にビルドできた。
Visual Studio 2013 Communityをインストールしているのでmsvcも試したが、こちらはエラーがたくさん出た。
まあ、そっちのことは何も考えずに作ってたからね・・・。
ともかくビルドできているので、コンパイラのパスを自動的に取得したりするところは動いているようだ。


今は、製品が4つあるようだ。

  • Community : ライセンス費無しで使える
  • Indie Moble : 毎月20ユーロ/25ドル
  • Professional : 毎月139ユーロ/174ドル
  • Enterprise : ご相談

Linux版では、BLEも対応しているらしい。
そっちは興味があるな。
Web開発機能にフォーカスした「Qt 5.4」がリリース | SourceForge.JP Magazine

 

gitoriousにQtプロジェクトがあるので、リンクを載せて今回の記事は終わろう。
Qt by Digia

[ble]long attributeのNotification

前に書いたが、NotificationやIndicationはデータサイズがATT_MTU-3までしか通知できない。
ATTの仕様としては、Core_v4.2 Vol.3 Part F 3.2の「3.2.9 Long Attribute Values」あたりに記載があり、1回のパケットではATT_MTU-1が最大だけど、それより大きいサイズのAttributeを定義することもできて、それは"long attribute"と呼ぶそうだ。その最大長は512byte(octだけど、面倒なのでbyteって書く)。

S110のGATT Serverではこうなってた。

/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths
 * @{ */
#define BLE_GATTS_FIX_ATTR_LEN_MAX (510)  /**< Maximum length for fixed length Attribute Values. */
#define BLE_GATTS_VAR_ATTR_LEN_MAX (512)  /**< Maximum length for variable length Attribute Values. */ 
/** @} */

 

ATT_MTU-3くらいのAttributeにしておくと設計とかはやりやすいし、データの取得なんかも楽になるんだけど、まあそうも言っていられない場合がある。
今回みたいに、NDEFのデータを読ませたい、とかなると、256byteくらいは確保しておきたい。

そうなると、Attributeのデータ長と、Notificationできるデータ長が異なることになる。
こういう非対称な場合、どうしたらいいんだろうか?
nRF51 SDKのAPIはNotificationするデータを設定できるようになっているので、必ずしもAttributeのデータを送らなくてもよいのだ。

よいけど、お作法としては同じデータの先頭から渡せる分だけを載せるのがよいのだろう。
だからこそ、「3.4.7.1 Handle Value Notification」の注意書きに、「long attributeが取得したいならこのnotificationの後でRead Blob Requestを使いなさい」ということが書いてあるのだろう。

2015/02/11

[ble]CCCDへなぜ書き込みをしたいのか?

GATT Tableを書きながら、まだまだBLEの勉強中。
今日はCCCD。

Client Characteristic Configuration Descriptionの略で、CCCD。
NotifyでCentralに通知したいときには準備する、くらいの認識だったが、もう少し調べてみた。

CCCDは2byte分のValueを持つCharacteristicだ。
中身はビットで、Notifyを許可するか、Indicateを許可するか、を表すことになっている。
だから、NotifyするCharacteristicにはCCCDを用意するのだ。

Permissionは、Readについては認証など不要で許可する。
Writeについては、アプリレベルでの認証というかがいるようだ。ただ「or is implementation specific」ともあるので、Writeは許可しなくてもよいのかもしれない。

Writeを許可するとどんなよいことがあるかというと、Notify/Indicateの有無をCentralから制御できることになる(Peripheralの意思に因るが)。
Central側が「もう来ないで!」と言って、Peripheralのアプリがそれを受け入れたら、PeripheralはNotify/Indicateを送らなくすることができる。そうすると、お互いの電力消費を抑えることができそうだ。

もしCCCDでNotify/Indicateが許可されていなければ、nRF51822ではsd_ble_gatts_hvx()でNRF_ERROR_INVALID_STATEを返すらしい。
How to know if the Notification/Indication of a Characteristic is enabled? - Nordic Developer Zone
なので「間違えてNotifyしてしまった!」ということは心配しなくてもよいが、戻り値をAPP_ERROR_CHECKマクロでチェックしてしまうとまずいかもしれない。

 

今日のまとめ。

  • CCCDは、現在Notify/Indicateができるかどうかを表している
  • 許可されていない場合に通知しようとすると、nRF51 SDK/SoftDeviceでエラーにしてくれる
  • CCCDに書込みを許容していると、Centralからも制御できる(CCCDのデフォルト値は通知不可)
  • 書き込みの際はアプリなどへの承認が必要っぽい

そうか、デフォルトで通知しないようになってるから、対向アプリで通知開始ボタンを押してやらないといけないのだな。


どうでもよいが、L2CAPとかI2CとかE2Pとかは省略したがるのに、CCCDはC3Dにならないのは不思議だ(発音の関連か)。
私は「I2C」は「あいつーしー」だし、「E2P」は「いーつーぴー」だ。

でも入社したときの上司が「E2P」を「E二乗P」と呼んでいたので、私は発音だけで「EGOP」と覚えてしまっていた。
まあ「いーすくうぇあぴー」を日本版にするとそうなるんだろうな。
インターネットで調べるのが普通になりつつある時代だったけど、さすがにEGOP-ROMでは検索はできなかったし、会話だけだと誰と話しても気付かれなかったし。
懐かしい話だ。

[ble]SSPの資料メモ

twitterを見てたら、NFC Forumの技術資料紹介があった。
これは、SSP(Secure Simple Pairing)についてだ。

 

 

以前、Static Handoverについて調べたことがあったけど、いつの間にかMediatedってのもできたんだねぇ。

2015/02/08

[ble]Attribute Tableを作ろう

nRF51822にサービスを何か載せる練習をしている。
前回、Input/Outputサービスを作ったときは、ドキュメントをまねしただけだった。
あれから私も勉強したので、もうちょっとちゃんと作ろうと思う。

これが、今回作ろうとしているものだ。

image

FeliCa Plugから読込み要求(Read w/o Enc.)が来たら、Notifyで通知する。
NFC R/W側に対しては、GATT Serverが持っているデータを渡すだけにしておく。
それと同じデータを、GATT Clientが読むこともできる。

あれこれいきなりやると時間がかかりそうだから、少しずつ動くものを作っていこう。


内部の方はまだ置いておくとして、GATT ServerとClient間のインターフェースを決めなくてはならん。
TIのSensorTagを見ると、attribute table[pdf]というものを用意していた。
うちにあるBLEのサンプルが少ないんだけど、この表を作るのがよいだろうと思う。
(GeckoTagは、技術サイトにログインできない件が解決できないので、何を公開しているかわからない。。。
 中の人、メール見てくれー)

Tableは、以下で構成されている。

  • Handle
  • Type
  • Value
  • Permission

TypeはDeclarationsにあった。
最初に「ここからService定義が始まる」というGATT Primary Service Declaration(0x2800)があり、そこから次のGATT Primary Serviceが現れるまではGATT Characteristic Declaration(0x2803)が続くという構造のようだ。
図にするとこんな感じか(Descriptorなどは省略)。

image

その辺を考え、nRF51822はこんなAttribute Tableがよいんじゃないか、と検討中。

image

Handleに相当する列がないのは、これはAPIによって決定するしくみになっていると思われるからだ。
UUIDさえ決めてしまえば、Handleは特に意識する必要は内容に思っている。
ひとまずこれで作ってみて、足りなかったら追加していこう。

2015/02/07

[excel]テーマの色 (2)

続ける予定はなかったのだが、前回の配色に疑惑が出てきた。

配色を変えて満足していたのだが、別のシートを見ると、既存のセルに書いていた文字色が消えていたのだ。
正確には、文字色が白になっていて、背景色が白のため見えなくなっていた。

ああ、これは重大な問題だ、と思ったのだが、配色を別のものにして、もう一度自分の作った配色を選び直すと、なぜかそういう状態にならないのだ。
配色に関して、何かバグがあるっぽい感じはするのだけど、そうだとしても正直なところ優先順位がかなり低いと思う。
回避もできるし、これを修正したとしても喜ぶ人はそこまで多くないんじゃなかろうか。

回避してしまえば、それまでダメだった新規シートの作成の文字色も、ちゃんと自動の黒になっている。
さっきまでのは何だったんだ・・・そんな思いにすら駆られてしまう。

だが、まあ、都合が悪いことを忘れるのも人間の美徳だ(根拠無し)。
そのときは、たまたまうまく動作しない状況になっていただけのことだろう。

2015/02/04

[excel]テーマの色

しばしば、Excelを使う。
家には、Excel2013を購入しているくらいだ。
まあ、仕事でずっと使っているから、もう別のを使うのが面倒になった、というのが正直なところかもしれない。

Excel(だけじゃなくてOffice全般かもしれんが)、テーマというのがある。
紛らわしいことに、Officeアプリのテーマという、アプリの見てくれを意味するテーマもあるのだが、そちらではなくてブックとかの単位で変更できるテーマのことをここでは指している。

image

こんなのね。
これで図形の文字色や背景色の選択パターンがデフォルトで決まる。
個別で選択することも可能だが、ここではテーマとして選択できる色についての話だけする。

デフォルトの「Office」というテーマでは、こんな色になるようだ。

image

悪くないのかもしれないが、私は白抜きの文字が苦手だ。
あまり、はっきり見えないのだ。
上の図では、左端の黒地に白はよいのだが、それ以外の白文字はちょっとつらい。
黒文字を選べばよいだけなのだが、その選択肢が少ないというのが、今困っているところなのだ。

 

そこで私なりにがんばった結果が、これだ。
(2015/02/07:配色に致命的欠陥あり!)

image

文字が白で見えないところもあるが、そこは捨てた。
とにかく、黒文字の選択肢を増やすことを重視した結果なのだ。
これは、「配色」の設定を変更している。

image

変更したのは「テキスト/背景」のところだ。
上から、白黒黒白、としている。

これを逆にして、黒白白黒、の順にすると、こうなる。

image

 

黒黒白黒、だと、これ。
2番目の色が、背景色に効いているのかな。
image

 

黒白黒黒、だと、こう。
あら、黒白白黒のパターンと同じだ。
image

 

では、黒黒黒黒。
うん、黒黒白黒と同じだ。
image


確認のため、黒黒白白。
やはり、黒黒白黒や、黒黒黒黒と同じ。
image

つまり、濃色2/淡色2は簡易選択するリストの中に入っていないということだ。


では、以降は最初の2つだけ見ていくことにしよう。

白白
image

黒白
image

白黒
image

黒黒
image

 

ということで、「濃色 1」が文字色を表している。
image

 

微妙な扱いなのが、「淡色 1」だ。
1行目については背景色を表していることになるが、それ以外では使われているように見えない。
無視してよいのか・・・。

無視するといえば、濃色2や淡色2も、ここに見えていないだけで他の役割をしている可能性はある。
嫌なのは、それがどこでどう影響しているかわからないことだ。
どういう影響を与えるか不透明なパラメータは、なるべく使わないようにしたい。
だから、テーマの配色はあまり使わない、というのが今の私の使い方になる。


新しい機能はなるべく使っていきたいのだが、ちょっとこのテーマの機能はねぇ、と思う。
簡単に使えるようにしていった結果なのかもしれないけど、自分の意図した配色を登録ができないので、どう使うにしても中途半端な印象がある。
もし、もっとできたとしても、こういう使い勝手しか表に見えないのであれば普及はしないように思う。

まあ、これもGUIのカスタマイズが難しいという現状を表しているということなのだろう。
UIは、既存の人と新規の人をどう両立させるかが大変そうだけど、がんばってほしいところだ。

2015/02/01

[ble]Limited DiscoveryとGeneral Discovery

Core_v4.2.pdf  p.2042
Vol.3 Part C  9.2 DISCOVERY MODES AND PROCEDURES

  • Non-Discoverable mode
  • Limited Discoverable mode
  • General Discoverable mode

Advertisingするだけなら、Non-Discoverable。
デバイス検出するのに操作がいり、一定時間だけ検出できるのが、Limited Discoverable。
特にそういう制限がないのが、General Discoverable。

という解釈だ。

[nrf51]app_error_handler()はWEAK

小ネタ。

nRF51 SDK v7でビルドしていると、DEBUGというマクロを定義するとエラーが発生した。
これは、app_error.cが使っていて、定義されている場合はbsp.hをincludeし、LEDを付けたりするように実装されているからだ。

そういえば、app_error_handler()は自前でも実装していたような気がして、確認するとやはり実装していた。
なのにリンクエラーが発生しない。
なんでだろう?

定義を見ると、こうなっていた。

__WEAK void app_error_handler(...)

このマクロは、__attribute__((weak))だった。
Function Attributes - Using the GNU Compiler Collection (GCC)
ライブラリ関数としてweakとしておけば、ユーザコードで上書きできるよ、みたいな感じらしい。
ほほぅ。

そんなわけで、app_error_handler()は自前でも実装できるし、してなかったらライブラリ側の実装が呼ばれる。
ライブラリ側は、DEBUGマクロがなければNVIC_SystemReset()を呼ぶだけになっている。